/*
 * 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 flashprog_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;
}
