/*
 * This file is part of the flashprog project.
 *
 * 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 <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <getopt.h>

#include "libflashprog.h"
#include "cli.h"

static void usage(const char *const name, const char *const msg)
{
	if (msg)
		fprintf(stderr, "\nError: %s\n", msg);

	fprintf(stderr, "\nUsage:"
			"\t%s [status] <options>\n"
			"\t%s  list    <options>\n"
			"\t%s  disable <options> [--temporary]\n"
			"\t%s  enable  <options> [--temporary]\n"
			"\t%s  range   <options> [--temporary] <start>,<len>\n"
			"\t%s  region  <options> [--temporary] <region-name>\n",
			name, name, name, name, name, name);
	fprintf(stderr, "\n"
		"A range is specified by two integers, the offset from the start of the flash\n"
		"and the length in bytes.  A region is specified by name from the layout, see\n"
		"layout options below.\n");
	print_generic_options(/* layout_options =>*/true);
	exit(1);
}

static int parse_wp_range(size_t *const start, size_t *const len, const char *const arg)
{
	size_t processed;

	if (sscanf(arg, "%zi,%zi%zn", start, len, &processed) != 2)
		return -1;

	if (*start > SIZE_MAX / 2 || *len > SIZE_MAX / 2)
		return -1;

	if (processed != strlen(arg))
		return -1;

	return 0;
}

static void print_wp_range(const char *const prefix,
			   struct flashprog_flashctx *const flash,
			   size_t start, size_t len)
{
	/* Start address and length */
	printf("%sstart=0x%08zx length=0x%08zx ", prefix, start, len);

	/* Easily readable description like 'none' or 'lower 1/8' */
	size_t chip_len = flashprog_flash_getsize(flash);

	if (len == 0) {
		printf("(none)\n");
	} else if (len == chip_len) {
		printf("(all)\n");
	} else {
		const char *location = "";
		if (start == 0)
			location = "lower ";
		if (start == chip_len - len)
			location = "upper ";

		/* Remove common factors of 2 to simplify */
		/* the (range_len/chip_len) fraction. */
		while ((chip_len % 2) == 0 && (len % 2) == 0) {
			chip_len /= 2;
			len /= 2;
		}

		printf("(%s%zu/%zu)\n", location, len, chip_len);
	}
}

static const char *get_wp_error_str(int err)
{
	switch (err) {
	case FLASHPROG_WP_ERR_CHIP_UNSUPPORTED:
		return "WP operations are not implemented for this chip";
	case FLASHPROG_WP_ERR_READ_FAILED:
		return "failed to read the current WP configuration";
	case FLASHPROG_WP_ERR_WRITE_FAILED:
		return "failed to write the new WP configuration";
	case FLASHPROG_WP_ERR_VERIFY_FAILED:
		return "unexpected WP configuration read back from chip";
	case FLASHPROG_WP_ERR_MODE_UNSUPPORTED:
		return "the requested protection mode is not supported";
	case FLASHPROG_WP_ERR_RANGE_UNSUPPORTED:
		return "the requested protection range is not supported";
	case FLASHPROG_WP_ERR_RANGE_LIST_UNAVAILABLE:
		return "could not determine what protection ranges are available";
	case FLASHPROG_WP_ERR_UNSUPPORTED_STATE:
		return "can't operate on current WP configuration of the chip";
	}
	return "unknown WP error";
}

static int wp_print_status(struct flashprog_flashctx *const flash)
{
	size_t start, len;
	enum flashprog_wp_mode mode;
	struct flashprog_wp_cfg *cfg = NULL;
	enum flashprog_wp_result ret;

	ret = flashprog_wp_cfg_new(&cfg);
	if (ret == FLASHPROG_WP_OK)
		ret = flashprog_wp_read_cfg(cfg, flash);

	if (ret != FLASHPROG_WP_OK) {
		fprintf(stderr, "Failed to get WP status: %s\n", get_wp_error_str(ret));
		flashprog_wp_cfg_release(cfg);
		return 1;
	}

	flashprog_wp_get_range(&start, &len, cfg);
	mode = flashprog_wp_get_mode(cfg);
	flashprog_wp_cfg_release(cfg);

	print_wp_range("Protection range: ", flash, start, len);

	const char *mode_desc;
	switch (mode) {
		case FLASHPROG_WP_MODE_DISABLED:    mode_desc = "disabled";	break;
		case FLASHPROG_WP_MODE_HARDWARE:    mode_desc = "hardware";	break;
		case FLASHPROG_WP_MODE_POWER_CYCLE: mode_desc = "power_cycle";	break;
		case FLASHPROG_WP_MODE_PERMANENT:   mode_desc = "permanent";	break;
		default:			    mode_desc = "unknown";	break;
	}
	printf("Protection mode: %s\n", mode_desc);

	return 0;
}

static int wp_print_ranges(struct flashprog_flashctx *const flash)
{
	struct flashprog_wp_ranges *list;
	size_t i;

	const enum flashprog_wp_result ret = flashprog_wp_get_available_ranges(&list, flash);
	if (ret != FLASHPROG_WP_OK) {
		fprintf(stderr, "Failed to get list of protection ranges: %s\n", get_wp_error_str(ret));
		return 1;
	}

	printf("Available protection ranges:\n");
	const size_t count = flashprog_wp_ranges_get_count(list);
	for (i = 0; i < count; i++) {
		size_t start, len;

		flashprog_wp_ranges_get_range(&start, &len, list, i);
		print_wp_range("\t", flash, start, len);
	}
	flashprog_wp_ranges_release(list);

	return 0;
}

static int wp_apply(struct flashprog_flashctx *const flash,
		    const bool enable_wp, const bool disable_wp,
		    const bool set_wp_range, const size_t wp_start,
		    const size_t wp_len)
{
	struct flashprog_wp_cfg *cfg;
	enum flashprog_wp_result ret;

	ret = flashprog_wp_cfg_new(&cfg);
	if (ret == FLASHPROG_WP_OK)
		ret = flashprog_wp_read_cfg(cfg, flash);

	if (ret != FLASHPROG_WP_OK) {
		fprintf(stderr, "Failed to get WP status: %s\n", get_wp_error_str(ret));
		flashprog_wp_cfg_release(cfg);
		return 1;
	}

	/* Store current WP mode for printing help text if changing the cfg fails. */
	const enum flashprog_wp_mode old_mode = flashprog_wp_get_mode(cfg);

	if (set_wp_range)
		flashprog_wp_set_range(cfg, wp_start, wp_len);

	if (disable_wp)
		flashprog_wp_set_mode(cfg, FLASHPROG_WP_MODE_DISABLED);

	if (enable_wp)
		flashprog_wp_set_mode(cfg, FLASHPROG_WP_MODE_HARDWARE);

	ret = flashprog_wp_write_cfg(flash, cfg);

	flashprog_wp_cfg_release(cfg);

	if (ret != FLASHPROG_WP_OK) {
		fprintf(stderr, "Failed to apply new WP settings: %s\n", get_wp_error_str(ret));

		if (ret != FLASHPROG_WP_ERR_VERIFY_FAILED)
			return 1;

		/* Warn user if active WP is likely to have caused failure */
		switch (old_mode) {
		case FLASHPROG_WP_MODE_HARDWARE:
			fprintf(stderr, "Note: hardware status register protection is enabled. "
				"The chip's WP# pin must be set to an inactive voltage "
				"level to be able to change the WP settings.\n");
			break;
		case FLASHPROG_WP_MODE_POWER_CYCLE:
			fprintf(stderr, "Note: power-cycle status register protection is enabled. "
				"A power-off, power-on cycle is usually required to change "
				"the chip's WP settings.\n");
			break;
		case FLASHPROG_WP_MODE_PERMANENT:
			fprintf(stderr, "Note: permanent status register protection is enabled. "
				"The chip's WP settings cannot be modified.\n");
			break;
		default:
			break;
		}
		return 1;
	}

	if (disable_wp)
		printf("Disabled hardware protection\n");

	if (enable_wp)
		printf("Enabled hardware protection\n");

	if (set_wp_range)
		print_wp_range("Configured protection range: ", flash, wp_start, wp_len);

	return 0;
}

int flashprog_wp_main(int argc, char *argv[])
{
	static const char optstring[] = "+p:c:Vo:hl:";
	static const struct option long_options[] = {
		{"programmer",		1, NULL, 'p'},
		{"chip",		1, NULL, 'c'},
		{"verbose",		0, NULL, 'V'},
		{"output",		1, NULL, 'o'},
		{"help",		0, NULL, 'h'},
		{"layout",		1, NULL, 'l'},
		{"ifd",			0, NULL, OPTION_IFD},
		{"fmap",		0, NULL, OPTION_FMAP},
		{"fmap-file",		1, NULL, OPTION_FMAP_FILE},
		{"temporary",		0, NULL, OPTION_CONFIG_VOLATILE},
		{"status",		0, NULL, OPTION_WP_STATUS},
		{"list",		0, NULL, OPTION_WP_LIST},
		{"range",		0, NULL, OPTION_WP_SET_RANGE},
		{"region",		0, NULL, OPTION_WP_SET_REGION},
		{"enable",		0, NULL, OPTION_WP_ENABLE},
		{"disable",		0, NULL, OPTION_WP_DISABLE},
		{NULL,			0, NULL, 0},
	};
	static const struct opt_command cmd_options[] = {
		{"status",		OPTION_WP_STATUS},
		{"list",		OPTION_WP_LIST},
		{"range",		OPTION_WP_SET_RANGE},
		{"region",		OPTION_WP_SET_REGION},
		{"enable",		OPTION_WP_ENABLE},
		{"disable",		OPTION_WP_DISABLE},
		{NULL,			0},
	};

	unsigned int ops = 0;
	int ret = 1, opt;
	struct log_args log_args = { FLASHPROG_MSG_INFO, FLASHPROG_MSG_DEBUG2, NULL };
	struct flash_args flash_args = { 0 };
	struct layout_args layout_args = { 0 };
	bool volat1le = false;
	bool enable_wp = false, disable_wp = false, print_wp_status = false;
	bool set_wp_range = false, set_wp_region = false, print_wp_ranges = false;
	size_t wp_start = 0, wp_len = 0;
	char *wp_region = NULL;

	if (cli_init()) /* TODO: Can be moved below argument parsing once usage() uses `stderr` directly. */
		goto free_ret;

	if (argc < 2)
		usage(argv[0], NULL);

	while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1 ||
	       (opt = getopt_command(argc, argv, cmd_options)) != -1) {
		switch (opt) {
		case 'V':
		case 'o':
			ret = cli_parse_log_args(&log_args, opt, optarg);
			if (ret == 1)
				usage(argv[0], NULL);
			else if (ret)
				goto free_ret;
			break;
		case 'p':
		case 'c':
			ret = cli_parse_flash_args(&flash_args, opt, optarg);
			if (ret == 1)
				usage(argv[0], NULL);
			else if (ret)
				goto free_ret;
			break;
		case OPTION_LAYOUT:
		case OPTION_IFD:
		case OPTION_FMAP:
		case OPTION_FMAP_FILE:
			ret = cli_parse_layout_args(&layout_args, opt, optarg);
			if (ret == 1)
				usage(argv[0], NULL);
			else if (ret)
				goto free_ret;
			break;
		case OPTION_CONFIG_VOLATILE:
			volat1le = true;
			break;
		case OPTION_WP_STATUS:
			print_wp_status = true;
			++ops;
			break;
		case OPTION_WP_LIST:
			print_wp_ranges = true;
			++ops;
			break;
		case OPTION_WP_SET_RANGE:
			set_wp_range = true;
			++ops;
			break;
		case OPTION_WP_SET_REGION:
			set_wp_region = true;
			++ops;
			break;
		case OPTION_WP_ENABLE:
			enable_wp = true;
			++ops;
			break;
		case OPTION_WP_DISABLE:
			disable_wp = true;
			++ops;
			break;
		case '?':
		case 'h':
			usage(argv[0], NULL);
			break;
		}
	}

	if (!ops) {
		print_wp_status = true;
		++ops;
	}
	if (ops > 1)
		usage(argv[0], "Only one operation may be specified.");

	if (!enable_wp && !disable_wp && !set_wp_range && !set_wp_region && volat1le)
		usage(argv[0], "`--temporary' may only be specified for write operations.");

	ret = 1;
	if (set_wp_range) {
		if (optind != argc - 1)
			usage(argv[0], "`range' requires exactly one argument.");
		if (parse_wp_range(&wp_start, &wp_len, argv[optind++]) < 0)
			usage(argv[0], "Incorrect wp-range arguments provided.");
	} else if (set_wp_region) {
		if (optind != argc - 1)
			usage(argv[0], "`region' requires exactly one argument.");
		wp_region = strdup(argv[optind++]);
		if (!wp_region) {
			fprintf(stderr, "Out of memory!\n");
			goto free_ret;
		}
	} else if (optind < argc) {
		usage(argv[0], "Extra parameter found.");
	}

	if (!flash_args.prog_name)
		usage(argv[0], "No programmer specified.");

	struct flashprog_programmer *prog;
	struct flashprog_flashctx *flash;
	struct flashprog_layout *layout = NULL;

	if (log_args.logfile && open_logfile(log_args.logfile))
		goto free_ret;
	verbose_screen = log_args.screen_level;
	verbose_logfile = log_args.logfile_level;
	start_logging();

	if (flashprog_programmer_init(&prog, flash_args.prog_name, flash_args.prog_args))
		goto free_ret;
	ret = flashprog_flash_probe(&flash, prog, flash_args.chip);
	if (ret == 3) {
		fprintf(stderr, "Multiple flash chip definitions match the detected chip.\n"
				"Please specify which chip definition to use with the -c <chipname> option.\n");
	} else if (ret) {
		fprintf(stderr, "No EEPROM/flash device found.\n");
		goto shutdown_ret;
	}

	flashprog_flag_set(flash, FLASHPROG_FLAG_NON_VOLATILE_WRSR, !volat1le);

	if (print_wp_status)
		ret = wp_print_status(flash);

	if (print_wp_ranges)
		ret = wp_print_ranges(flash);

	if (set_wp_region) {
		ret = 1;
		if (cli_process_layout_args(&layout, flash, &layout_args)) {
			fprintf(stderr, "Failed to read layout.\n");
			goto release_ret;
		}
		if (!layout) {
			fprintf(stderr, "Error: `--region' operation requires a layout.\n");
			goto release_ret;
		}

		if (flashprog_layout_get_region_range(layout, wp_region, &wp_start, &wp_len)) {
			fprintf(stderr, "Cannot find region '%s'.\n", wp_region);
			goto release_ret;
		}
		set_wp_range = true;
	}

	if (set_wp_range || enable_wp || disable_wp)
		ret = wp_apply(flash, enable_wp, disable_wp, set_wp_range, wp_start, wp_len);

release_ret:
	flashprog_layout_release(layout);
	flashprog_flash_release(flash);
shutdown_ret:
	flashprog_programmer_shutdown(prog);
free_ret:
	free(wp_region);
	free(layout_args.fmapfile);
	free(layout_args.layoutfile);
	free(flash_args.chip);
	free(flash_args.prog_args);
	free(flash_args.prog_name);
	free(log_args.logfile);
	close_logfile();
	return ret;
}
