/*
 * Copyright 2012, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *      disclaimer in the documentation and/or other materials provided
 *      with the distribution.
 *    * Neither the name of Google Inc. nor the names of its
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include "mosys/alloc.h"
#include "mosys/big_lock.h"
#include "mosys/command_list.h"
#include "mosys/globals.h"
#include "mosys/kv_pair.h"
#include "mosys/log.h"
#include "mosys/output.h"
#include "mosys/platform.h"

static void usage(void)
{
	printf("usage: %s [options] [commands]\n\n"
	"  Options:\n"
	"    -k            print data in key=value format\n"
	"    -l            print data in long format\n"
	"    -s [key]      print value for single key\n"
	"    -v            verbose (can be used multiple times)\n"
	"    -f            force (ignore mosys lock, sanity checks, etc)\n"
	"    -t            display command tree for detected platform\n"
	"    -S            print supported platform IDs\n"
	"    -p [id]       specify platform id (bypass auto-detection)\n"
	"    -h            print this help\n"
	"    -V            print version\n"
	"\n", PROGRAM);
}

static void sub_list(struct platform_cmd *sub)
{
	struct platform_cmd *_sub;

	if (!sub)
		return;

	printf("  Commands:\n");
	for (_sub = sub->arg.sub; _sub && _sub->name; _sub++) {
		if (_sub->desc)
			printf("    %-12s  %s\n", _sub->name, _sub->desc);
	}
	printf("\n");
}

static int sub_main(struct platform_intf *intf,
		    struct platform_cmd *sub, int argc, char **argv)
{
	struct platform_cmd *cmd;

	if (!intf || !sub) {
		errno = ENOSYS;
		return -1;
	}

	switch (sub->type) {
	case ARG_TYPE_GETTER:
	case ARG_TYPE_SETTER:
		if (!sub->arg.func) {
			lprintf(LOG_ERR, "Undefined Function\n");
			return -1;
		}

		/* this is a function, it might have more args */
		if (argc > 0 && strcmp(argv[0], "help") == 0) {
			platform_cmd_usage(sub);
			return 0;
		}

		/* run command handler */
		return sub->arg.func(intf, sub, argc, argv);

	case ARG_TYPE_SUB:
		if (argc == 0) {
			sub_list(sub);
			return -1;	/* generic error */
		}

		/* this is a sub-command, we must have some more args */
		if (argc == 0 || strcmp(argv[0], "help") == 0) {
			sub_list(sub);
			return 0;
		}

		/* search for matching sub-command */
		for (cmd = sub->arg.sub; cmd && cmd->name; cmd++) {
			if (strlen(cmd->name) != strlen(argv[0]))
				continue;
			if (strcmp(cmd->name, argv[0]) == 0) {
				lprintf(LOG_DEBUG, "Subcommand %s (%s)\n",
					cmd->name, cmd->desc);
				return sub_main(intf, cmd, argc - 1,
						&(argv[1]));
			}
		}
		break;

	default:
		lprintf(LOG_ERR, "Unknown subcommand type\n");
		return -1;
	}

	lprintf(LOG_WARNING, "Command not found\n\n");
	sub_list(sub);

	errno = EINVAL;	/* unknown or invalid subcommand argument */
	return -1;
}

static int intf_main(struct platform_intf *intf, int argc, char **argv)
{
	struct platform_cmd **_sub, *sub;
	int do_list = 0;
	int ret = 0;

	if (!intf || !intf->sub) {
		lprintf(LOG_ERR, "No commands defined for this platform\n");
		errno = ENOSYS;
		return -1;
	}

	if (argc == 0 || strcmp(argv[0], "help") == 0) {
		do_list = 1;
		usage();
		printf("  Commands:\n");
	}

	/* go through subcommand list for this interface */
	for (_sub = intf->sub; _sub && *_sub; _sub++) {

		sub = *_sub;
		if (do_list) {
			/*FIXME: if the intf had a main sub, call sub_list */
			printf("    %-12s  %s\n", sub->name, sub->desc);
			continue;
		}

		lprintf(LOG_DEBUG, "Command: %s (%s)\n", sub->name, argv[0]);

		/* is this sub-command is the one they asked for? */
		if (strlen(sub->name) != strlen(argv[0]))
			continue;
		if (strcmp(sub->name, argv[0]) == 0) {
			lprintf(LOG_DEBUG, "Found command %s (%s)\n",
				sub->name, sub->desc);
			return sub_main(intf, sub, argc - 1, &(argv[1]));
		}
	}

	if (do_list) {
		printf("\n");
		if (argc == 0)
			ret = -1;
		return ret;
	}

	lprintf(LOG_WARNING, "Command not found\n\n");
	errno = ENOSYS;
	return intf_main(intf, 0, NULL);	/* trigger a help listing */
}

#define LOCK_TIMEOUT_SECS 180

int mosys_main(int argc, char **argv)
{
	int rc, errsv;
	int argflag;
	int verbose = 0;
	int force_lock = 0;
	int print_platforms_opt = 0;
	int showtree = 0;
	char *p_opt = NULL;
	struct platform_intf *intf;
	enum kv_pair_style style = KV_STYLE_VALUE;

	while ((argflag = getopt(argc, argv, "klvftSs:p:Vh")) > 0) {
		switch (argflag) {
		case 'k':
			style = KV_STYLE_PAIR;
			break;
		case 'l':
			style = KV_STYLE_LONG;
			break;
		case 's':
			style = KV_STYLE_SINGLE;
			if (!optarg) {
				usage();
				exit(EXIT_FAILURE);
			}
			kv_set_single_key(optarg);
			break;
		case 'v':
			verbose++;
			break;
		case 'f':
			force_lock = 1;
			break;
		case 't':
			showtree = 1;
			break;
		case 'S':
			print_platforms_opt = 1;
			break;
		case 'p':
			p_opt = optarg;
			break;
		case 'V':
			printf("mosys version %s\n", VERSION);
			exit(EXIT_SUCCESS);
		case 'h':
			usage();
			exit(EXIT_SUCCESS);
		default:
			usage();
			exit(EXIT_FAILURE);
		}
	}

	mosys_set_kv_pair_style(style);
	if (print_platforms_opt)
		return print_platforms();

	/*
	 * Init the logging system and the default log output file (stderr).
	 * Anything logged with a level above CONFIG_LOGLEVEL will not be logged
	 * at all. We use the number of "-v" arguments on the commandline as
	 * a bias against the default threshold.  The more times you use
	 * "-v", the greater your logging level becomes, and the more
	 * information will be printed.
	 */
	mosys_log_init(PROGRAM, CONFIG_LOGLEVEL+verbose, NULL);

#if defined(CONFIG_USE_IPC_LOCK)
	/* try to get lock */
	if (!force_lock && (mosys_acquire_big_lock(LOCK_TIMEOUT_SECS) < 0)) {
		rc = -1;
		goto do_exit_1;
	}
#endif

	/* set the global verbosity level */
	mosys_set_verbosity(CONFIG_LOGLEVEL+verbose);

	/* try to identify the platform */
	intf = mosys_platform_setup(p_opt);
	if (!intf) {
		lprintf(LOG_ERR, "Platform not supported\n");
		rc = -1;
		goto do_exit_2;
	}
	lprintf(LOG_DEBUG, "Platform: %s\n", intf->name);

	if (showtree) {
		print_tree(intf);
		rc = 0;
		goto do_exit_3;
	}

	/* run command */
	errno = 0;
	rc = intf_main(intf, argc - optind, &(argv[optind]));
	errsv = errno;
	if (rc < 0 && errsv == ENOSYS)
		lprintf(LOG_ERR, "Command not supported on this platform\n");

	/* clean up */
do_exit_3:
	mosys_platform_destroy(intf);
do_exit_2:
#if defined(CONFIG_USE_IPC_LOCK)
	mosys_release_big_lock();
#endif
do_exit_1:
	mosys_log_halt();

	if (rc < 0 && errsv > 0)
		exit(errsv);
	exit(rc);
}

int main(int argc, char **argv)
{
	mosys_globals_init();
	return mosys_main(argc, argv);
}
