/*
 * 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-2014 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 <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#include "flash.h"
#include "cli.h"

int cli_check_filename(const char *const filename, const char *const type)
{
	if (!filename || (filename[0] == '\0')) {
		fprintf(stderr, "Error: No %s file specified.\n", type);
		return 1;
	}
	/* Not an error, but maybe the user intended to specify a CLI option instead of a file name. */
	if (filename[0] == '-' && filename[1] != '\0')
		fprintf(stderr, "Warning: Supplied %s file name starts with -\n", type);
	return 0;
}

int cli_parse_flash_args(struct flash_args *const args, const int opt, const char *const optarg)
{
	switch (opt) {
	case OPTION_PROGRAMMER:
		if (args->prog_name) {
			fprintf(stderr,
				"Error: --programmer specified more than once. You can separate multiple\n"
				"arguments for a programmer with ','. Please see the man page for details.\n");
			return 1;
		}
		const char *const colon = strchr(optarg, ':');
		if (colon) {
			args->prog_name = strndup(optarg, colon - optarg);
			args->prog_args = strdup(colon + 1);
		} else {
			args->prog_name = strdup(optarg);
		}
		if (!args->prog_name || (colon && !args->prog_args)) {
			fprintf(stderr, "Out of memory!\n");
			return 2;
		}
		break;
	case OPTION_CHIP:
		if (args->chip) {
			fprintf(stderr, "Error: --chip specified more than once.\n");
			return 1;
		}
		args->chip = strdup(optarg);
		if (!args->chip) {
			fprintf(stderr, "Out of memory!\n");
			return 2;
		}
		break;
	}

	return 0;
}

int cli_parse_layout_args(struct layout_args *const args, const int opt, const char *const optarg)
{
	if (args->layoutfile || args->ifd || args->fmap || args->fmapfile) {
		fprintf(stderr, "Error: Only one layout source may be specified.\n");
		return 1;
	}

	switch (opt) {
	case OPTION_LAYOUT:
		if (cli_check_filename(optarg, "layout"))
			return 1;

		args->layoutfile = strdup(optarg);
		if (!args->layoutfile) {
			fprintf(stderr, "Out of memory!\n");
			return 2;
		}
		break;
	case OPTION_IFD:
		args->ifd = true;
		break;
	case OPTION_FMAP:
		args->fmap = true;
		break;
	case OPTION_FMAP_FILE:
		if (cli_check_filename(optarg, "fmap"))
			return 1;

		args->fmapfile = strdup(optarg);
		if (!args->fmapfile) {
			fprintf(stderr, "Out of memory!\n");
			return 2;
		}
		break;
	}

	return 0;
}

int cli_process_layout_args(struct flashprog_layout **const layout,
			    struct flashprog_flashctx *const flash,
			    const struct layout_args *const args)
{
	*layout = NULL;

	if (args->layoutfile) {
		if (layout_from_file(layout, args->layoutfile))
			return 1;
	} else if (args->ifd) {
		if (flashprog_layout_read_from_ifd(layout, flash, NULL, 0))
			return 1;
	} else if (args->fmap) {
		if (flashprog_layout_read_fmap_from_rom(layout, flash, 0, flashprog_flash_getsize(flash)))
			return 1;
	} else if (args->fmapfile) {
		struct stat s;
		if (stat(args->fmapfile, &s) != 0) {
			msg_gerr("Failed to stat fmapfile \"%s\"\n", args->fmapfile);
			return 1;
		}

		size_t fmapfile_size = s.st_size;
		uint8_t *fmapfile_buffer = malloc(fmapfile_size);
		if (!fmapfile_buffer) {
			fprintf(stderr, "Out of memory!\n");
			return 1;
		}

		if (read_buf_from_file(fmapfile_buffer, fmapfile_size, args->fmapfile)) {
			free(fmapfile_buffer);
			return 1;
		}

		if (flashprog_layout_read_fmap_from_buffer(layout, flash, fmapfile_buffer, fmapfile_size)) {
			free(fmapfile_buffer);
			return 1;
		}
		free(fmapfile_buffer);
	}

	return 0;
}

void print_chip_support_status(const struct flashchip *chip)
{
	if (chip->feature_bits & FEATURE_OTP) {
		msg_cdbg("This chip may contain one-time programmable memory. flashprog cannot read\n"
			 "and may never be able to write it, hence it may not be able to completely\n"
			 "clone the contents of this chip (see man page for details).\n");
	}

	if ((chip->tested.erase == NA) && (chip->tested.write == NA)) {
		msg_cdbg("This chip's main memory can not be erased/written by design.\n");
	}

	if ((chip->tested.probe == BAD) || (chip->tested.probe == NT) ||
	    (chip->tested.read == BAD)  || (chip->tested.read == NT) ||
	    (chip->tested.erase == BAD) || (chip->tested.erase == NT) ||
	    (chip->tested.write == BAD) || (chip->tested.write == NT)) {
		msg_cinfo("===\n");
		if ((chip->tested.probe == BAD) ||
		    (chip->tested.read == BAD) ||
		    (chip->tested.erase == BAD) ||
		    (chip->tested.write == BAD)) {
			msg_cinfo("This flash part has status NOT WORKING for operations:");
			if (chip->tested.probe == BAD)
				msg_cinfo(" PROBE");
			if (chip->tested.read == BAD)
				msg_cinfo(" READ");
			if (chip->tested.erase == BAD)
				msg_cinfo(" ERASE");
			if (chip->tested.write == BAD)
				msg_cinfo(" WRITE");
			msg_cinfo("\n");
		}
		if ((chip->tested.probe == NT) ||
		    (chip->tested.read == NT) ||
		    (chip->tested.erase == NT) ||
		    (chip->tested.write == NT)) {
			msg_cinfo("This flash part has status UNTESTED for operations:");
			if (chip->tested.probe == NT)
				msg_cinfo(" PROBE");
			if (chip->tested.read == NT)
				msg_cinfo(" READ");
			if (chip->tested.erase == NT)
				msg_cinfo(" ERASE");
			if (chip->tested.write == NT)
				msg_cinfo(" WRITE");
			msg_cinfo("\n");
		}
		msg_cinfo("The test status of this chip may have been updated in the latest development\n"
			  "version of flashprog. If you are running the latest development version,\n"
			  "please email a report to flashprog@flashprog.org if any of the above\n"
			  "operations work correctly for you with this flash chip. Please include the\n"
			  "flashprog log file for all operations you tested (see the man page for details),\n"
			  "and mention which mainboard or programmer you tested in the subject line.\n"
			  "Thanks for your help!\n");
	}
}
