/*
 * 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/dynui.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 dynamic user interface name
 *
 * @v text		Text
 * @ret dynui		Dynamic user interface
 * @ret rc		Return status code
 */
int parse_dynui ( char *text, struct dynamic_ui **dynui ) {

	/* Find user interface */
	*dynui = find_dynui ( text );
	if ( ! *dynui ) {
		if ( text ) {
			printf ( "\"%s\": no such user interface\n", text );
		} else {
			printf ( "No default user interface\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 );
}
