/*
 * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <ipxe/uuid.h>
#include <ipxe/netdevice.h>
#include <ipxe/menu.h>
#include <ipxe/settings.h>
#include <ipxe/params.h>
#include <ipxe/timer.h>
#include <ipxe/keys.h>
#include <ipxe/parseopt.h>
#include <config/branding.h>

/** @file
 *
 * Command line option parsing
 *
 */

/** Return status code for "--help" option */
#define ECANCELED_NO_OP __einfo_error ( EINFO_ECANCELED_NO_OP )
#define EINFO_ECANCELED_NO_OP \
	__einfo_uniqify ( EINFO_ECANCELED, 0x01, "Nothing to do" )

/* Disambiguate the various error codes */
#define EINVAL_INTEGER __einfo_error ( EINFO_EINVAL_INTEGER )
#define EINFO_EINVAL_INTEGER \
	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid integer value" )
#define EINVAL_UNKNOWN_OPTION __einfo_error ( EINFO_EINVAL_UNKNOWN_OPTION )
#define EINFO_EINVAL_UNKNOWN_OPTION \
	__einfo_uniqify ( EINFO_EINVAL, 0x02, "Unrecognised option" )
#define EINVAL_MISSING_ARGUMENT __einfo_error ( EINFO_EINVAL_MISSING_ARGUMENT )
#define EINFO_EINVAL_MISSING_ARGUMENT \
	__einfo_uniqify ( EINFO_EINVAL, 0x03, "Missing argument" )

/**
* Parse string value
 *
 * @v text		Text
 * @ret value		String value
 * @ret rc		Return status code
 */
int parse_string ( char *text, char **value ) {

	/* Sanity check */
	assert ( text != NULL );

	/* Parse string */
	*value = text;

	return 0;
}

/**
 * Parse integer value
 *
 * @v text		Text
 * @ret value		Integer value
 * @ret rc		Return status code
 */
int parse_integer ( char *text, unsigned int *value ) {
	char *endp;

	/* Sanity check */
	assert ( text != NULL );

	/* Parse integer */
	*value = strtoul ( text, &endp, 0 );
	if ( *endp || ( ! *text ) ) {
		printf ( "\"%s\": invalid integer value\n", text );
		return -EINVAL_INTEGER;
	}

	return 0;
}

/**
 * Parse timeout value (in ms)
 *
 * @v text		Text
 * @ret value		Integer value
 * @ret rc		Return status code
 */
int parse_timeout ( char *text, unsigned long *value ) {
	unsigned int value_ms;
	int rc;

	/* Parse raw integer value */
	if ( ( rc = parse_integer ( text, &value_ms ) ) != 0 )
		return rc;

	/* Convert to a number of timer ticks */
	*value = ( value_ms * TICKS_PER_MS );

	return 0;
}

/**
 * Parse UUID
 *
 * @v text		Text
 * @ret uuid		UUID value
 * @ret rc		Return status code
 */
int parse_uuid ( char *text, struct uuid_option *uuid ) {
	int rc;

	/* Sanity check */
	assert ( text != NULL );

	/* Parse UUID */
	if ( ( rc = uuid_aton ( text, &uuid->buf ) ) != 0 ) {
		printf ( "\"%s\": invalid UUID\n", text );
		return rc;
	}
	uuid->value = &uuid->buf;

	return 0;
}

/**
 * Parse network device name
 *
 * @v text		Text
 * @ret netdev		Network device
 * @ret rc		Return status code
 */
int parse_netdev ( char *text, struct net_device **netdev ) {

	/* Sanity check */
	assert ( text != NULL );

	/* Find network device */
	*netdev = find_netdev ( text );
	if ( ! *netdev ) {
		printf ( "\"%s\": no such network device\n", text );
		return -ENODEV;
	}

	return 0;
}

/**
 * Parse network device configurator name
 *
 * @v text		Text
 * @ret configurator	Network device configurator
 * @ret rc		Return status code
 */
int parse_netdev_configurator ( char *text,
				struct net_device_configurator **configurator ){

	/* Sanity check */
	assert ( text != NULL );

	/* Find network device configurator */
	*configurator = find_netdev_configurator ( text );
	if ( ! *configurator ) {
		printf ( "\"%s\": no such configurator\n", text );
		return -ENOTSUP;
	}

	return 0;
}

/**
 * Parse menu name
 *
 * @v text		Text
 * @ret menu		Menu
 * @ret rc		Return status code
 */
int parse_menu ( char *text, struct menu **menu ) {

	/* Find menu */
	*menu = find_menu ( text );
	if ( ! *menu ) {
		if ( text ) {
			printf ( "\"%s\": no such menu\n", text );
		} else {
			printf ( "No default menu\n" );
		}
		return -ENOENT;
	}

	return 0;
}

/**
 * Parse flag
 *
 * @v text		Text (ignored)
 * @ret flag		Flag to set
 * @ret rc		Return status code
 */
int parse_flag ( char *text __unused, int *flag ) {

	/* Set flag */
	*flag = 1;

	return 0;
}

/**
 * Parse key
 *
 * @v text		Text
 * @ret key		Key
 * @ret rc		Return status code
 */
int parse_key ( char *text, unsigned int *key ) {
	int rc;

	/* Interpret single characters as being a literal key character */
	if ( text[0] && ! text[1] ) {
		*key = text[0];
		return 0;
	}

	/* Otherwise, interpret as an integer */
	if ( ( rc = parse_integer ( text, key ) ) < 0 )
		return rc;

	/* For backwards compatibility with existing scripts, treat
	 * integers between the ASCII range and special key range as
	 * being relative special key values.
	 */
	if ( ( ! isascii ( *key ) ) && ( *key < KEY_MIN ) )
		*key += KEY_MIN;

	return 0;
}

/**
 * Parse settings block name
 *
 * @v text		Text
 * @ret value		Integer value
 * @ret rc		Return status code
 */
int parse_settings ( char *text, struct settings **value ) {

	/* Sanity check */
	assert ( text != NULL );

	/* Parse scope name */
	*value = find_settings ( text );
	if ( ! *value ) {
		printf ( "\"%s\": no such scope\n", text );
		return -EINVAL;
	}

	return 0;
}

/**
 * Parse setting name
 *
 * @v text		Text
 * @v setting		Named setting to fill in
 * @v get_child		Function to find or create child settings block
 * @ret rc		Return status code
 *
 * Note that this function modifies the original @c text.
 */
int parse_setting ( char *text, struct named_setting *setting,
		    get_child_settings_t get_child ) {
	int rc;

	/* Sanity check */
	assert ( text != NULL );

	/* Parse setting name */
	if ( ( rc = parse_setting_name ( text, get_child, &setting->settings,
					 &setting->setting ) ) != 0 ) {
		printf ( "\"%s\": invalid setting\n", text );
		return rc;
	}

	return 0;
}

/**
 * Parse existing setting name
 *
 * @v text		Text
 * @v setting		Named setting to fill in
 * @ret rc		Return status code
 *
 * Note that this function modifies the original @c text.
 */
int parse_existing_setting ( char *text, struct named_setting *setting ) {

	return parse_setting ( text, setting, find_child_settings );
}

/**
 * Parse and autovivify setting name
 *
 * @v text		Text
 * @v setting		Named setting to fill in
 * @ret rc		Return status code
 *
 * Note that this function modifies the original @c text.
 */
int parse_autovivified_setting ( char *text, struct named_setting *setting ) {

	return parse_setting ( text, setting, autovivify_child_settings );
}

/**
 * Parse request parameter list name
 *
 * @v text		Text
 * @ret params		Parameter list
 * @ret rc		Return status code
 */
int parse_parameters ( char *text, struct parameters **params ) {

	/* Find parameter list */
	*params = find_parameters ( text );
	if ( ! *params ) {
		if ( text ) {
			printf ( "\"%s\": no such parameter list\n", text );
		} else {
			printf ( "No default parameter list\n" );
		}
		return -ENOENT;
	}

	return 0;
}

/**
 * Print command usage message
 *
 * @v cmd		Command descriptor
 * @v argv		Argument list
 */
void print_usage ( struct command_descriptor *cmd, char **argv ) {
	struct option_descriptor *option;
	unsigned int i;
	int is_optional;

	printf ( "Usage:\n\n  %s", argv[0] );
	for ( i = 0 ; i < cmd->num_options ; i++ ) {
		option = &cmd->options[i];
		printf ( " [-%c|--%s", option->shortopt, option->longopt );
		if ( option->has_arg ) {
			is_optional = ( option->has_arg == optional_argument );
			printf ( " %s<%s>%s", ( is_optional ? "[" : "" ),
				 option->longopt, ( is_optional ? "]" : "" ) );
		}
		printf ( "]" );
	}
	if ( cmd->usage )
		printf ( " %s", cmd->usage );
	printf ( "\n\nSee " PRODUCT_COMMAND_URI " for further information\n",
		 argv[0] );
}

/**
 * Reparse command-line options
 *
 * @v argc		Argument count
 * @v argv		Argument list
 * @v cmd		Command descriptor
 * @v opts		Options (already initialised with default values)
 * @ret rc		Return status code
 */
int reparse_options ( int argc, char **argv, struct command_descriptor *cmd,
		      void *opts ) {
	struct option longopts[ cmd->num_options + 1 /* help */ + 1 /* end */ ];
	char shortopts[ cmd->num_options * 3 /* possible "::" */ + 1 /* "h" */
			+ 1 /* NUL */ ];
	unsigned int shortopt_idx = 0;
	int ( * parse ) ( char *text, void *value );
	void *value;
	unsigned int i;
	unsigned int j;
	unsigned int num_args;
	int c;
	int rc;

	/* Construct long and short option lists for getopt_long() */
	memset ( longopts, 0, sizeof ( longopts ) );
	for ( i = 0 ; i < cmd->num_options ; i++ ) {
		longopts[i].name = cmd->options[i].longopt;
		longopts[i].has_arg = cmd->options[i].has_arg;
		longopts[i].val = cmd->options[i].shortopt;
		shortopts[shortopt_idx++] = cmd->options[i].shortopt;
		assert ( cmd->options[i].has_arg <= optional_argument );
		for ( j = cmd->options[i].has_arg ; j > 0 ; j-- )
			shortopts[shortopt_idx++] = ':';
	}
	longopts[i].name = "help";
	longopts[i].val = 'h';
	shortopts[shortopt_idx++] = 'h';
	shortopts[shortopt_idx++] = '\0';
	assert ( shortopt_idx <= sizeof ( shortopts ) );
	DBGC ( cmd,  "Command \"%s\" has options \"%s\", %d-%d args, len %d\n",
	       argv[0], shortopts, cmd->min_args, cmd->max_args, cmd->len );

	/* Parse options */
	while ( ( c = getopt_long ( argc, argv, shortopts, longopts,
				    NULL ) ) >= 0 ) {
		switch ( c ) {
		case 'h' :
			/* Print help */
			print_usage ( cmd, argv );
			return -ECANCELED_NO_OP;
		case '?' :
			/* Print usage message */
			print_usage ( cmd, argv );
			return -EINVAL_UNKNOWN_OPTION;
		case ':' :
			/* Print usage message */
			print_usage ( cmd, argv );
			return -EINVAL_MISSING_ARGUMENT;
		default:
			/* Search for an option to parse */
			for ( i = 0 ; i < cmd->num_options ; i++ ) {
				if ( c != cmd->options[i].shortopt )
					continue;
				parse = cmd->options[i].parse;
				value = ( opts + cmd->options[i].offset );
				if ( ( rc = parse ( optarg, value ) ) != 0 )
					return rc;
				break;
			}
			assert ( i < cmd->num_options );
		}
	}

	/* Check remaining arguments */
	num_args = ( argc - optind );
	if ( ( num_args < cmd->min_args ) || ( num_args > cmd->max_args ) ) {
		print_usage ( cmd, argv );
		return -ERANGE;
	}

	return 0;
}

/**
 * Parse command-line options
 *
 * @v argc		Argument count
 * @v argv		Argument list
 * @v cmd		Command descriptor
 * @v opts		Options (may be uninitialised)
 * @ret rc		Return status code
 */
int parse_options ( int argc, char **argv, struct command_descriptor *cmd,
		    void *opts ) {

	/* Clear options */
	memset ( opts, 0, cmd->len );

	return reparse_options ( argc, argv, cmd, opts );
}
