/*
 * 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;
	struct flashprog_voltage_range voltage;
	struct flashprog_test_status tested;
	const struct flashprog_chip *chip;
	struct flashprog_chips *chips;
	char *s;
	char *ven, *dev;
	const char *tmpven, *tmpdev;
	char *tmpven_save, *tmpdev_save;
	int tmpvenlen, tmpdevlen, curvenlen, curdevlen;

	if (flashprog_chips_all(&chips))
		return 1;

	/* calculate maximum column widths and by iterating over all chips */
	for (chip = flashprog_chip_first(chips); chip; chip = flashprog_chip_next(chip)) {
		chipcount++;

		/* Find maximum vendor length (respecting line splitting). */
		tmpven = flashprog_chip_vendor(chip);
		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 = flashprog_chip_name(chip);
		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 = flashprog_chip_bus_names(chip);
		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 = flashprog_chip_first(chips); chip; chip = flashprog_chip_next(chip)) {
		/* 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(flashprog_chip_vendor(chip)) + 1);
		if (ven == NULL) {
			msg_gerr("Out of memory!\n");
			flashprog_chips_release(chips);
			return 1;
		}
		strcpy(ven, flashprog_chip_vendor(chip));

		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(flashprog_chip_name(chip)) + 1);
		if (dev == NULL) {
			msg_gerr("Out of memory!\n");
			flashprog_chips_release(chips);
			free(ven);
			return 1;
		}
		strcpy(dev, flashprog_chip_name(chip));

		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(" ");

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

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

		msg_ginfo("%6zu", flashprog_chip_size(chip) / KiB);
		for (i = 0; i < border; i++)
			msg_ginfo(" ");

		s = flashprog_chip_bus_names(chip);
		msg_ginfo("%s", s);
		for (i = strlen(s); i < maxtypelen; i++)
			msg_ginfo(" ");
		free(s);

		voltage = flashprog_chip_voltage_range(chip);
		if (voltage.min == 0 && voltage.max == 0)
			msg_gdbg("no info");
		else
			msg_gdbg("%0.02f;%0.02f", voltage.min, voltage.max);

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

	flashprog_chips_release(chips);
	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;
}
