/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
 * Copyright (C) 2009 Carl-Daniel Hailfinger
 * Copyright (C) 2011-2013 Stefan Tauner
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#if HAVE_UTSNAME == 1
#include <sys/utsname.h>
#endif
#if IS_WINDOWS
#include <windows.h>
#undef min
#undef max
#endif

#include "flash.h"
#include "programmer.h"

static void print_sysinfo(void)
{
#if IS_WINDOWS
	SYSTEM_INFO si = { 0 };
	OSVERSIONINFOEX osvi = { 0 };

	msg_ginfo(" on Windows");
	/* Tell Windows which version of the structure we want. */
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
	if (GetVersionEx((OSVERSIONINFO*) &osvi))
		msg_ginfo(" %lu.%lu", (unsigned long)osvi.dwMajorVersion,
			(unsigned long)osvi.dwMinorVersion);
	else
		msg_ginfo(" unknown version");
	GetSystemInfo(&si);
	switch (si.wProcessorArchitecture) {
	case PROCESSOR_ARCHITECTURE_AMD64:
		msg_ginfo(" (x86_64)");
		break;
	case PROCESSOR_ARCHITECTURE_INTEL:
		msg_ginfo(" (x86)");
		break;
	default:
		msg_ginfo(" (unknown arch)");
		break;
	}
#elif HAVE_UTSNAME == 1
	struct utsname osinfo;

	uname(&osinfo);
	msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
		  osinfo.machine);
#else
	msg_ginfo(" on unknown machine");
#endif
}

void print_buildinfo(void)
{
	msg_gdbg("flashprog was built with");
#ifdef __clang__
	msg_gdbg(" LLVM Clang");
#ifdef __clang_version__
	msg_gdbg(" %s,", __clang_version__);
#else
	msg_gdbg(" unknown version (before r102686),");
#endif
#elif defined(__GNUC__)
	msg_gdbg(" GCC");
#ifdef __VERSION__
	msg_gdbg(" %s,", __VERSION__);
#else
	msg_gdbg(" unknown version,");
#endif
#else
	msg_gdbg(" unknown compiler,");
#endif
#if defined (__FLASHPROG_LITTLE_ENDIAN__)
	msg_gdbg(" little endian");
#elif defined (__FLASHPROG_BIG_ENDIAN__)
	msg_gdbg(" big endian");
#else
#error Endianness could not be determined
#endif
	msg_gdbg("\n");
}

void print_version(void)
{
	msg_ginfo("flashprog %s", flashprog_version);
	print_sysinfo();
	msg_ginfo("\n");
}

void print_banner(void)
{
	msg_ginfo("flashprog is free software, get the source code at "
		  "https://flashprog.org\n");
	msg_ginfo("\n");
}

static const char *test_state_to_text(enum test_state test_state)
{
	switch (test_state) {
	case OK: return "OK";
	case BAD: return "Not working";
	case NA: return "N/A";
	case DEP: return "Config-dependent";
	case NT:
	default: return "Untested";
	}
}

static int print_supported_chips(void)
{
	const char *delim = "/";
	const int mintoklen = 5;
	const int border = 2;
	int i, chipcount = 0;
	int maxvendorlen = strlen("Vendor") + 1;
	int maxchiplen = strlen("Device") + 1;
	int maxtypelen = strlen("Type") + 1;
	const struct flashchip *chip;
	char *s;
	char *ven, *dev;
	char *tmpven, *tmpdev, *tmpven_save, *tmpdev_save;
	int tmpvenlen, tmpdevlen, curvenlen, curdevlen;

	/* calculate maximum column widths and by iterating over all chips */
	for (chip = flashchips; chip->name != NULL; chip++) {
		/* Ignore generic entries. */
		if (!strncmp(chip->vendor, "Unknown", 7) ||
		    !strncmp(chip->vendor, "Programmer", 10) ||
		    !strncmp(chip->name, "unknown", 7))
			continue;
		chipcount++;

		/* Find maximum vendor length (respecting line splitting). */
		tmpven = (char *)chip->vendor;
		do {
			/* and take minimum token lengths into account */
			tmpvenlen = 0;
			do {
				tmpvenlen += strcspn(tmpven, delim);
				/* skip to the address after the first token */
				tmpven += tmpvenlen;
				if (tmpven[0] == '\0')
					break;
				tmpven++;
			} while (tmpvenlen < mintoklen);
			maxvendorlen = max(maxvendorlen, tmpvenlen);
			if (tmpven[0] == '\0')
				break;
		} while (1);

		/* same for device name */
		tmpdev = (char *)chip->name;
		do {
			tmpdevlen = 0;
			do {
				tmpdevlen += strcspn(tmpdev, delim);
				tmpdev += tmpdevlen;
				if (tmpdev[0] == '\0')
					break;
				tmpdev++;
			} while (tmpdevlen < mintoklen);
			maxchiplen = max(maxchiplen, tmpdevlen);
			if (tmpdev[0] == '\0')
				break;
		} while (1);

		s = flashbuses_to_text(chip->bustype);
		maxtypelen = max(maxtypelen, strlen(s));
		free(s);
	}
	maxvendorlen += border;
	maxchiplen += border;
	maxtypelen += border;

	msg_ginfo("Supported flash chips (total: %d):\n\n", chipcount);
	msg_ginfo("Vendor");
	for (i = strlen("Vendor"); i < maxvendorlen; i++)
		msg_ginfo(" ");
	msg_ginfo("Device");
	for (i = strlen("Device"); i < maxchiplen; i++)
		msg_ginfo(" ");

	msg_ginfo("Test");
	for (i = 0; i < border; i++)
		msg_ginfo(" ");
	msg_ginfo("Known");
	for (i = 0; i < border; i++)
		msg_ginfo(" ");
	msg_ginfo(" Size ");
	for (i = 0; i < border; i++)
		msg_ginfo(" ");

	msg_ginfo("Type");
	for (i = strlen("Type"); i < maxtypelen; i++)
		msg_ginfo(" ");
	msg_gdbg("Voltage");
	msg_ginfo("\n");

	for (i = 0; i < maxvendorlen + maxchiplen; i++)
		msg_ginfo(" ");
	msg_ginfo("OK  ");
	for (i = 0; i < border; i++)
		msg_ginfo(" ");
	msg_ginfo("Broken");
	for (i = 0; i < border; i++)
		msg_ginfo(" ");
	msg_ginfo("[kB] ");
	for (i = 0; i < border + maxtypelen; i++)
		msg_ginfo(" ");
	msg_gdbg("range [V]");
	msg_ginfo("\n\n");
	msg_ginfo("(P = PROBE, R = READ, E = ERASE, W = WRITE, - = N/A)\n\n");

	for (chip = flashchips; chip->name != NULL; chip++) {
		/* Don't print generic entries. */
		if (!strncmp(chip->vendor, "Unknown", 7) ||
		    !strncmp(chip->vendor, "Programmer", 10) ||
		    !strncmp(chip->name, "unknown", 7))
			continue;

		/* support for multiline vendor names:
		 * - make a copy of the original vendor name
		 * - use strok to put the first token in tmpven
		 * - keep track of the length of all tokens on the current line
		 *   for ' '-padding in curvenlen
		 * - check if additional tokens should be printed on the current
		 *   line
		 * - after all other values are printed print the surplus tokens
		 *   on fresh lines
		 */
		ven = malloc(strlen(chip->vendor) + 1);
		if (ven == NULL) {
			msg_gerr("Out of memory!\n");
			return 1;
		}
		strcpy(ven, chip->vendor);

		tmpven = strtok_r(ven, delim, &tmpven_save);
		msg_ginfo("%s", tmpven);
		curvenlen = strlen(tmpven);
		while ((tmpven = strtok_r(NULL, delim, &tmpven_save)) != NULL) {
			msg_ginfo("%s", delim);
			curvenlen++;
			tmpvenlen = strlen(tmpven);
			if (tmpvenlen >= mintoklen)
				break; /* big enough to be on its own line */
			msg_ginfo("%s", tmpven);
			curvenlen += tmpvenlen;
		}

		for (i = curvenlen; i < maxvendorlen; i++)
			msg_ginfo(" ");

		/* support for multiline device names as above */
		dev = malloc(strlen(chip->name) + 1);
		if (dev == NULL) {
			msg_gerr("Out of memory!\n");
			free(ven);
			return 1;
		}
		strcpy(dev, chip->name);

		tmpdev = strtok_r(dev, delim, &tmpdev_save);
		msg_ginfo("%s", tmpdev);
		curdevlen = strlen(tmpdev);
		while ((tmpdev = strtok_r(NULL, delim, &tmpdev_save)) != NULL) {
			msg_ginfo("%s", delim);
			curdevlen++;
			tmpdevlen = strlen(tmpdev);
			if (tmpdevlen >= mintoklen)
				break; /* big enough to be on its own line */
			msg_ginfo("%s", tmpdev);
			curdevlen += tmpdevlen;
		}

		for (i = curdevlen; i < maxchiplen; i++)
			msg_ginfo(" ");

		if (chip->tested.probe == OK)
			msg_ginfo("P");
		else if (chip->tested.probe == NA)
			msg_ginfo("-");
		else
			msg_ginfo(" ");
		if (chip->tested.read == OK)
			msg_ginfo("R");
		else if (chip->tested.read == NA)
			msg_ginfo("-");
		else
			msg_ginfo(" ");
		if (chip->tested.erase == OK)
			msg_ginfo("E");
		else if (chip->tested.erase == NA)
			msg_ginfo("-");
		else
			msg_ginfo(" ");
		if (chip->tested.write == OK)
			msg_ginfo("W");
		else if (chip->tested.write == NA)
			msg_ginfo("-");
		else
			msg_ginfo(" ");
		for (i = 0; i < border; i++)
			msg_ginfo(" ");

		if (chip->tested.probe == BAD)
			msg_ginfo("P");
		else
			msg_ginfo(" ");
		if (chip->tested.read == BAD)
			msg_ginfo("R");
		else
			msg_ginfo(" ");
		if (chip->tested.erase == BAD)
			msg_ginfo("E");
		else
			msg_ginfo(" ");
		if (chip->tested.write == BAD)
			msg_ginfo("W");
		else
			msg_ginfo(" ");
		for (i = 0; i < border + 1; i++)
			msg_ginfo(" ");

		msg_ginfo("%6d", chip->total_size);
		for (i = 0; i < border; i++)
			msg_ginfo(" ");

		s = flashbuses_to_text(chip->bustype);
		msg_ginfo("%s", s);
		for (i = strlen(s); i < maxtypelen; i++)
			msg_ginfo(" ");
		free(s);

		if (chip->voltage.min == 0 && chip->voltage.max == 0)
			msg_gdbg("no info");
		else
			msg_gdbg("%0.02f;%0.02f",
				 chip->voltage.min/(double)1000,
				 chip->voltage.max/(double)1000);

		/* print surplus vendor and device name tokens */
		while (tmpven != NULL || tmpdev != NULL) {
			msg_ginfo("\n");
			if (tmpven != NULL){
				msg_ginfo("%s", tmpven);
				curvenlen = strlen(tmpven);
				while ((tmpven = strtok_r(NULL, delim, &tmpven_save)) != NULL) {
					msg_ginfo("%s", delim);
					curvenlen++;
					tmpvenlen = strlen(tmpven);
					/* big enough to be on its own line */
					if (tmpvenlen >= mintoklen)
						break;
					msg_ginfo("%s", tmpven);
					curvenlen += tmpvenlen;
				}
			} else
				curvenlen = 0;

			for (i = curvenlen; i < maxvendorlen; i++)
				msg_ginfo(" ");

			if (tmpdev != NULL){
				msg_ginfo("%s", tmpdev);
				curdevlen = strlen(tmpdev);
				while ((tmpdev = strtok_r(NULL, delim, &tmpdev_save)) != NULL) {
					msg_ginfo("%s", delim);
					curdevlen++;
					tmpdevlen = strlen(tmpdev);
					/* big enough to be on its own line */
					if (tmpdevlen >= mintoklen)
						break;
					msg_ginfo("%s", tmpdev);
					curdevlen += tmpdevlen;
				}
			}
		}
		msg_ginfo("\n");
		free(ven);
		free(dev);
	}

	return 0;
}

#if CONFIG_INTERNAL == 1
static void print_supported_chipsets(void)
{
	unsigned int i, chipsetcount = 0;
	const struct penable *c = chipset_enables;
	size_t maxvendorlen = strlen("Vendor") + 1;
	size_t maxchipsetlen = strlen("Chipset") + 1;

	for (c = chipset_enables; c->vendor_name != NULL; c++) {
		chipsetcount++;
		maxvendorlen = MAX(maxvendorlen, strlen(c->vendor_name));
		maxchipsetlen = MAX(maxchipsetlen, strlen(c->device_name));
	}
	maxvendorlen++;
	maxchipsetlen++;

	msg_ginfo("Supported chipsets (total: %u):\n\n", chipsetcount);

	msg_ginfo("Vendor");
	for (i = strlen("Vendor"); i < maxvendorlen; i++)
		msg_ginfo(" ");

	msg_ginfo("Chipset");
	for (i = strlen("Chipset"); i < maxchipsetlen; i++)
		msg_ginfo(" ");

	msg_ginfo("PCI IDs    Status\n\n");

	for (c = chipset_enables; c->vendor_name != NULL; c++) {
		msg_ginfo("%s", c->vendor_name);
		for (i = 0; i < maxvendorlen - strlen(c->vendor_name); i++)
			msg_ginfo(" ");
		msg_ginfo("%s", c->device_name);
		for (i = 0; i < maxchipsetlen - strlen(c->device_name); i++)
			msg_ginfo(" ");
		msg_ginfo("%04x:%04x  %s\n", c->vendor_id, c->device_id,
		       test_state_to_text(c->status));
	}
}

static void print_supported_boards_helper(const struct board_info *boards,
				   const char *devicetype)
{
	unsigned int i;
	unsigned int boardcount_good = 0, boardcount_bad = 0, boardcount_nt = 0;
	const struct board_match *e = board_matches;
	const struct board_info *b = boards;
	size_t maxvendorlen = strlen("Vendor") + 1;
	size_t maxboardlen = strlen("Board") + 1;

	for (b = boards; b->vendor != NULL; b++) {
		maxvendorlen = max(maxvendorlen, strlen(b->vendor));
		maxboardlen = max(maxboardlen, strlen(b->name));
		if (b->working == OK)
			boardcount_good++;
		else if (b->working == NT)
			boardcount_nt++;
		else
			boardcount_bad++;
	}
	maxvendorlen++;
	maxboardlen++;

	msg_ginfo("%d known %s (good: %d, untested: %d, bad: %d):\n\n",
		  boardcount_good + boardcount_nt + boardcount_bad,
		  devicetype, boardcount_good, boardcount_nt, boardcount_bad);

	msg_ginfo("Vendor");
	for (i = strlen("Vendor"); i < maxvendorlen; i++)
		msg_ginfo(" ");

	msg_ginfo("Board");
	for (i = strlen("Board"); i < maxboardlen; i++)
		msg_ginfo(" ");

	msg_ginfo("Status  Required value for\n");
	for (i = 0; i < maxvendorlen + maxboardlen + strlen("Status  "); i++)
		msg_ginfo(" ");
	msg_ginfo("-p internal:mainboard=\n");

	for (b = boards; b->vendor != NULL; b++) {
		msg_ginfo("%s", b->vendor);
		for (i = 0; i < maxvendorlen - strlen(b->vendor); i++)
			msg_ginfo(" ");
		msg_ginfo("%s", b->name);
		for (i = 0; i < maxboardlen - strlen(b->name); i++)
			msg_ginfo(" ");

		switch (b->working) {
		case OK:  msg_ginfo("OK      "); break;
		case NT:  msg_ginfo("NT      "); break;
		case DEP: msg_ginfo("DEP     "); break;
		case NA:  msg_ginfo("N/A     "); break;
		case BAD:
		default:  msg_ginfo("BAD     "); break;
		}

		for (e = board_matches; e->vendor_name != NULL; e++) {
			if (strcmp(e->vendor_name, b->vendor)
			    || strcmp(e->board_name, b->name))
				continue;
			if (e->lb_vendor == NULL)
				msg_ginfo("(autodetected)");
			else
				msg_ginfo("%s:%s", e->lb_vendor,
						   e->lb_part);
		}
		msg_ginfo("\n");
	}
}
#endif

static void print_supported_devs(const struct programmer_entry *const prog, const char *const type)
{
	const struct dev_entry *const devs = prog->devs.dev;
	msg_ginfo("\nSupported %s devices for the %s programmer:\n", type, prog->name);
	unsigned int maxvendorlen = strlen("Vendor") + 1;
	unsigned int maxdevlen = strlen("Device") + 1;

	unsigned int i;
	for (i = 0; devs[i].vendor_name != NULL; i++) {
		maxvendorlen = max(maxvendorlen, strlen(devs[i].vendor_name));
		maxdevlen = max(maxdevlen, strlen(devs[i].device_name));
	}
	maxvendorlen++;
	maxdevlen++;

	msg_ginfo("Vendor");
	for (i = strlen("Vendor"); i < maxvendorlen; i++)
		msg_ginfo(" ");

	msg_ginfo("Device");
	for (i = strlen("Device"); i < maxdevlen; i++)
		msg_ginfo(" ");

	msg_ginfo(" %s IDs    Status\n", type);

	for (i = 0; devs[i].vendor_name != NULL; i++) {
		msg_ginfo("%s", devs[i].vendor_name);
		unsigned int j;
		for (j = strlen(devs[i].vendor_name); j < maxvendorlen; j++)
			msg_ginfo(" ");
		msg_ginfo("%s", devs[i].device_name);
		for (j = strlen(devs[i].device_name); j < maxdevlen; j++)
			msg_ginfo(" ");

		msg_pinfo(" %04x:%04x  %s\n", devs[i].vendor_id, devs[i].device_id,
			  test_state_to_text(devs[i].status));
	}
}

int print_supported(void)
{
	unsigned int i;
	if (print_supported_chips())
		return 1;

	msg_ginfo("\nSupported programmers:\n");
	list_programmers_linebreak(0, 80, 0);
	msg_ginfo("\n");
#if CONFIG_INTERNAL == 1
	msg_ginfo("\nSupported devices for the internal programmer:\n\n");
	print_supported_chipsets();
	msg_ginfo("\n");
	print_supported_boards_helper(boards_known, "mainboards");
	msg_ginfo("\n");
	print_supported_boards_helper(laptops_known, "mobile devices");
#endif
	for (i = 0; i < programmer_table_size; i++) {
		const struct programmer_entry *const prog = programmer_table[i];
		switch (prog->type) {
		case USB:
			print_supported_devs(prog, "USB");
			break;
		case PCI:
			print_supported_devs(prog, "PCI");
			break;
		case OTHER:
			if (prog->devs.note != NULL) {
				msg_ginfo("\nSupported devices for the %s programmer:\n", prog->name);
				msg_ginfo("%s", prog->devs.note);
			}
			break;
		default:
			msg_gerr("\n%s: %s: Uninitialized programmer type!\n"
				 "Please report a bug at flashprog@flashprog.org\n",
				 __func__, prog->name);
			break;
		}
	}
	return 0;
}
