/*
 * Copyright (c) 2018 Oticon A/S
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "nsi_tracing.h"
#include "nsi_cmdline.h"
#include "nsi_cmdline_internal.h"
#include "nsi_cpu_es_if.h"

/**
 * Check if <arg> is the option <option>
 * The accepted syntax is:
 *   * For options without a value following:
 *       [-[-]]<option>
 *   * For options with value:
 *       [-[-]]<option>{:|=}<value>
 *
 * Returns 0 if it is not, or a number > 0 if it is.
 * The returned number is the number of characters it went through
 * to find the end of the option including the ':' or '=' character in case of
 * options with value
 */
int nsi_cmd_is_option(const char *arg, const char *option, int with_value)
{
	int of = 0;
	size_t to_match_len = strlen(option);

	if (arg[of] == '-') {
		of++;
	}
	if (arg[of] == '-') {
		of++;
	}

	if (!with_value) {
		if (strcmp(&arg[of], option) != 0) {
			return 0;
		} else {
			return of + to_match_len;
		}
	}

	while (!(arg[of] == 0 && *option == 0)) {
		if (*option == 0) {
			if ((arg[of] == ':') || (arg[of] == '=')) {
				of++;
				break;
			}
			return 0;
		}
		if (arg[of] != *option) {
			return 0;
		}
		of++;
		option++;
	}

	if (arg[of] == 0) { /* we need a value to follow */
		nsi_print_error_and_exit("Incorrect option syntax '%s'. The "
					 "value should follow the options. "
					 "For example --ratio=3\n",
					 arg);
	}
	return of;
}

/**
 * Return 1 if <arg> matches an accepted help option.
 * 0 otherwise
 *
 * Valid help options are [-[-]]{?|h|help}
 * with the h or help in any case combination
 */
int nsi_cmd_is_help_option(const char *arg)
{
	if (arg[0] == '-') {
		arg++;
	}
	if (arg[0] == '-') {
		arg++;
	}
	if ((strcasecmp(arg, "?") == 0) ||
	    (strcasecmp(arg, "h") == 0) ||
	    (strcasecmp(arg, "help") == 0)) {
		return 1;
	} else {
		return 0;
	}
}

#define CMD_TYPE_ERROR "Coding error: type %c not understood"
#define CMD_ERR_BOOL_SWI "Programming error: I only know how to "\
	"automatically read boolean switches\n"

/**
 * Read out a the value following an option from str, and store it into
 * <dest>
 * <type> indicates the type of parameter (and type of dest pointer)
 *   'b' : boolean
 *   's' : string (char *)
 *   'u' : 32 bit unsigned integer
 *   'U' : 64 bit unsigned integer
 *   'i' : 32 bit signed integer
 *   'I' : 64 bit signed integer
 *   'd' : *double* float
 *
 * Note: list type ('l') cannot be handled by this function and must always be
 *       manual
 *
 *  <long_d> is the long name of the option
 */
void nsi_cmd_read_option_value(const char *str, void *dest, const char type,
			   const char *option)
{
	int error = 0;
	char *endptr = NULL;

	switch (type) {
	case 'b':
		if (strcasecmp(str, "false") == 0) {
			*(bool *)dest = false;
			endptr = (char *)str + 5;
		} else if (strcmp(str, "0") == 0) {
			*(bool *)dest = false;
			endptr = (char *)str + 1;
		} else if (strcasecmp(str, "true") == 0) {
			*(bool *)dest = true;
			endptr = (char *)str + 4;
		} else if (strcmp(str, "1") == 0) {
			*(bool *)dest = true;
			endptr = (char *)str + 1;
		} else {
			error = 1;
		}
		break;
	case 's':
		*(char **)dest = (char *)str;
		endptr = (char *)str + strlen(str);
		break;
	case 'u':
		*(uint32_t *)dest = strtoul(str, &endptr, 0);
		break;
	case 'U':
		*(uint64_t *)dest = strtoull(str, &endptr, 0);
		break;
	case 'i':
		*(int32_t *)dest = strtol(str, &endptr, 0);
		break;
	case 'I':
		*(int64_t *)dest = strtoll(str, &endptr, 0);
		break;
	case 'd':
		*(double *)dest = strtod(str, &endptr);
		break;
	default:
		nsi_print_error_and_exit(CMD_TYPE_ERROR, type);
		/* Unreachable */
		break;
	}

	if (!error && endptr && *endptr != 0) {
		error = 1;
	}

	if (error) {
		nsi_print_error_and_exit("Error reading value of %s '%s'. Use"
					   " --help for usage information\n",
					   option, str);
	}
}

/**
 * Initialize existing dest* to defaults based on type
 */
void nsi_cmd_args_set_defaults(struct args_struct_t args_struct[])
{
	int count = 0;

	while (args_struct[count].option != NULL) {

		if (args_struct[count].dest == NULL) {
			count++;
			continue;
		}

		switch (args_struct[count].type) {
		case 0: /* does not have storage */
			break;
		case 'b':
			*(bool *)args_struct[count].dest = false;
			break;
		case 's':
			*(char **)args_struct[count].dest = NULL;
			break;
		case 'u':
			*(uint32_t *)args_struct[count].dest = UINT32_MAX;
			break;
		case 'U':
			*(uint64_t *)args_struct[count].dest = UINT64_MAX;
			break;
		case 'i':
			*(int32_t *)args_struct[count].dest = INT32_MAX;
			break;
		case 'I':
			*(int64_t *)args_struct[count].dest = INT64_MAX;
			break;
		case 'd':
			*(double *)args_struct[count].dest = (double)NAN;
			break;
		default:
			nsi_print_error_and_exit(CMD_TYPE_ERROR,
						   args_struct[count].type);
			break;
		}
		count++;
	}
}

/**
 * For the help messages:
 * Generate a string containing how the option described by <args_s_el>
 * should be used
 *
 * The string is saved in <buf> which has been allocated <size> bytes by the
 * caller
 */
static void nsi_cmd_gen_switch_syntax(char *buf, int size,
				  struct args_struct_t *args_s_el)
{
	int ret = 0;

	if (size <= 0) {
		return;
	}

	if (args_s_el->is_mandatory == false) {
		*buf++ = '[';
		size--;
	}

	if (args_s_el->is_switch == true) {
		ret = snprintf(buf, size, "-%s", args_s_el->option);
	} else {
		if (args_s_el->type != 'l') {
			ret = snprintf(buf, size, "-%s=<%s>",
					args_s_el->option, args_s_el->name);
		} else {
			ret = snprintf(buf, size, "-%s <%s>...",
					args_s_el->option, args_s_el->name);
		}
	}

	if (ret < 0) {
		nsi_print_error_and_exit("Unexpected error in %s %i\n",
					   __FILE__, __LINE__);
	}
	if (size - ret < 0) {
		/*
		 * If we run out of space we can just stop,
		 * this is not critical
		 */
		return;
	}
	buf += ret;
	size -= ret;

	if (args_s_el->is_mandatory == false) {
		snprintf(buf, size, "] ");
	} else {
		snprintf(buf, size, " ");
	}
}

/**
 * Print short list of available switches
 */
void nsi_cmd_print_switches_help(struct args_struct_t args_struct[])
{
	int count = 0;
	int printed_in_line = strlen(_HELP_SWITCH) + 1;

	fprintf(stdout, "%s ", _HELP_SWITCH);

	while (args_struct[count].option != NULL) {
		char stringy[_MAX_STRINGY_LEN];

		nsi_cmd_gen_switch_syntax(stringy, _MAX_STRINGY_LEN,
				      &args_struct[count]);

		if (printed_in_line + strlen(stringy) > _MAX_LINE_WIDTH) {
			fprintf(stdout, "\n");
			printed_in_line = 0;
		}

		fprintf(stdout, "%s", stringy);
		printed_in_line += strlen(stringy);
		count++;
	}

	fprintf(stdout, "\n");
}

/**
 * Print the long help message of the program
 */
void nsi_cmd_print_long_help(struct args_struct_t args_struct[])
{
	int ret;
	int count = 0;
	int printed_in_line = 0;
	char stringy[_MAX_STRINGY_LEN];

	nsi_cmd_print_switches_help(args_struct);

	fprintf(stdout, "\n %-*s:%s\n", _LONG_HELP_ALIGN-1,
		_HELP_SWITCH, _HELP_DESCR);

	while (args_struct[count].option != NULL) {
		int printed_right;
		char *toprint;
		int total_to_print;

		nsi_cmd_gen_switch_syntax(stringy, _MAX_STRINGY_LEN,
				      &args_struct[count]);

		ret = fprintf(stdout, " %-*s:", _LONG_HELP_ALIGN-1, stringy);
		printed_in_line = ret;
		printed_right = 0;
		toprint = args_struct[count].descript;
		total_to_print = strlen(toprint);
		ret = fprintf(stdout, "%.*s\n",
				_MAX_LINE_WIDTH - printed_in_line,
				&toprint[printed_right]);
		printed_right += ret - 1;

		while (printed_right < total_to_print) {
			fprintf(stdout, "%*s", _LONG_HELP_ALIGN, "");
			ret = fprintf(stdout, "%.*s\n",
				      _MAX_LINE_WIDTH - _LONG_HELP_ALIGN,
				      &toprint[printed_right]);
			printed_right += ret - 1;
		}
		count++;
	}
	fprintf(stdout, "\n");
	fprintf(stdout, "Note that which options are available depends on the "
		"enabled features/drivers\n\n");
}

/*
 * <argv> matched the argument described in <arg_element>
 *
 * If arg_element->dest points to a place to store a possible value, read it
 * If there is a callback registered, call it after
 */
static void nsi_cmd_handle_this_matched_arg(char *argv, int offset,
					struct args_struct_t *arg_element)
{
	if (arg_element->dest != NULL) {
		if (arg_element->is_switch) {
			if (arg_element->type == 'b') {
				*(bool *)arg_element->dest = true;
			} else {
				nsi_print_error_and_exit(CMD_ERR_BOOL_SWI);
			}
		} else { /* if not a switch we need to read its value */
			nsi_cmd_read_option_value(&argv[offset],
					      arg_element->dest,
					      arg_element->type,
					      arg_element->option);
		}
	}

	if (arg_element->call_when_found) {
		arg_element->call_when_found(argv, offset);
	}
}

/**
 * Try to find if this argument is in the list (and it is not manual)
 * if it does, try to parse it, set its dest accordingly, and return true
 * if it is not found, return false
 */
bool nsi_cmd_parse_one_arg(char *argv, struct args_struct_t args_struct[])
{
	int count = 0;
	int ret;

	if (nsi_cmd_is_help_option(argv)) {
		nsi_cmd_print_long_help(args_struct);
		nsi_exit(0);
	}

	while (args_struct[count].option != NULL) {
		if (args_struct[count].manual) {
			count++;
			continue;
		}
		ret = nsi_cmd_is_option(argv, args_struct[count].option,
				    !args_struct[count].is_switch);
		if (ret) {
			nsi_cmd_handle_this_matched_arg(argv,
						    ret,
						    &args_struct[count]);
			return true;
		}
		count++;
	}
	return false;
}
