/* 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.
 *
 * platform.c: platform interface routines
 */

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

#include "mosys/alloc.h"
#include "mosys/callbacks.h"
#include "mosys/globals.h"
#include "mosys/intf_list.h"
#include "mosys/kv_pair.h"
#include "mosys/log.h"
#include "mosys/platform.h"
#include "mosys/output.h"

#include "lib/string.h"

#ifndef LINE_MAX
#define LINE_MAX 64
#endif

/*
 * mosys_platform_setup  -  identify platform, setup interfaces and commands
 *
 * @p_opt:	Optional platform name given to bypass auto-detection
 * 
 * returns pointer to identified platform interface
 * returns NULL if platform not identified or other error
 */
struct platform_intf *mosys_platform_setup(const char *p_opt)
{
	struct platform_intf **_intf, *intf;
	struct platform_intf *ret = NULL;
	int intf_found = 0;

	/* attempt to probe platform name and match it to an interface */
	for (_intf = platform_intf_list; _intf && *_intf; _intf++) {
		intf = *_intf;

		lprintf(LOG_DEBUG, "Checking platform %s\n", intf->name);

		/* use common operations by default */
		intf->op = &platform_common_op;

		/* platform name specified by user */
		if (p_opt) {
			if (strlfind(p_opt, &intf->id_list[0], 0)) {
				intf_found = 1;
				break;
			} else {
				continue;
			}
		}

		/* auto-detect */
		if (intf->probe) {
			int rc = intf->probe(intf);

			if (rc < 0) {
				lprintf(LOG_DEBUG, "Error encountered when "
					"probing %s\n", intf->name);
				continue;
			} else if (rc > 0) {
				lprintf(LOG_DEBUG, "Platform %s found (via "
				"probing)\n", intf->name);
				intf_found = 1;
				break;
			}
		}
	}

	if (!intf_found)
		goto mosys_platform_setup_exit;

	/* call platform-specific setup if found */
	if (intf->setup && intf->setup(intf) < 0)
		goto mosys_platform_setup_exit;

	/* prepare interface operations */
	if (intf_op_setup(intf) < 0) {
		if (intf->destroy)
			intf->destroy(intf);
		intf_op_destroy(intf);
		goto mosys_platform_setup_exit;
	}

	/* call platform-specific post-setup if found */
	if (intf->setup_post &&
	    intf->setup_post(intf) < 0) {
		if (intf->destroy)
			intf->destroy(intf);
		goto mosys_platform_setup_exit;
	}

	ret = intf;

mosys_platform_setup_exit:
	return ret;
}

/*
 * mosys_platform_destroy  -  clean up platform interface
 *
 * @intf:	platform interface
 */
void mosys_platform_destroy(struct platform_intf *intf)
{
	/* Call the destroy callbacks and cleanup afterwards. */
//	invoke_destroy_callbacks();
//	cleanup_destroy_callbacks();

	if (intf) {
		/* cleanup interface */
		if (intf->destroy)
			intf->destroy(intf);

		/* cleanup interface operations */
		intf_op_destroy(intf);

	}
}

/*
 * platform_cmd_usage  -  print usage text for command
 *
 * @cmd:	command pointer
 */
void platform_cmd_usage(struct platform_cmd *cmd)
{
	printf("usage: %s %s\n\n", cmd->name, cmd->usage ? : "");
}

/*
 * tree_sub -	subcommand handler for print_tree
 *
 * @intf:	platform interface
 * @cmd:	command to iterate thru
 * @depth:	depth of recursion (number of leading tabs to prepend)
 * @str:	string with full command name
 *
 * returns 0 to indicate success
 * returns <0 to indicate failure (or end of command hierarchy)
 */
static int tree_subcommand(struct platform_intf *intf,
			   struct platform_cmd *cmd,
			   int depth, char *str)
{
	struct platform_cmd *sub;
	char *tabs;
	int index;

	tabs = mosys_malloc(depth + 1);
	memset(tabs, '\t', depth);
	tabs[depth] = '\0';

	for (sub = cmd->arg.sub, index = 1; sub->name != NULL; sub++, index++) {
		printf("%s", tabs);

		if (sub->type == ARG_TYPE_SUB) {
			int pos = 0, len = 0;

			if (mosys_get_verbosity() >= LOG_NOTICE) {
				printf("[branch] %s ", str);

				/* add full command info */
				pos = strlen(str);
				len = LINE_MAX - strlen(str);
				snprintf(str + pos, len, " %s", sub->name);
			}

			printf("%s\n", sub->name);

			/* continue descending into the hierarchy */
			tree_subcommand(intf, sub, depth + 1, str);

			if (mosys_get_verbosity() >= LOG_NOTICE) {
				memset(str + pos, 0, len);
			}
		} else if (sub->type == ARG_TYPE_GETTER) {
			if (mosys_get_verbosity() >= LOG_NOTICE)
				printf("[leaf] %s ", str);
			printf("%s\n", sub->name);
		} else if (sub->type == ARG_TYPE_SETTER) {
			if (mosys_get_verbosity() >= LOG_NOTICE)
				printf("[flur] %s ", str);
			printf("%s\n", sub->name);
		} else {
			// not a subcommand or function?!?
			return -1;
		}

	}

	free(tabs);
	return 0;
}

/*
 * print_tree - print command tree for this platform
 *
 * @intf:	platform interface
 */
void print_tree(struct platform_intf *intf)
{
	int root;
	char str[LINE_MAX];

	for (root = 0; intf->sub[root] != NULL; root++) {
		if (mosys_get_verbosity() >= LOG_NOTICE) {
			printf("[root] ");
			snprintf(str, sizeof(str), "mosys %s",
						   intf->sub[root]->name);
		} else {
			snprintf(str, sizeof(str), "%s", intf->sub[root]->name);
		}
		printf("%s\n", str);

		if (tree_subcommand(intf, intf->sub[root], 1, str) < 0)
			lprintf(LOG_DEBUG, "tree walking failed: %s", str);
	}
}

/*
 * print_platforms - print platform ids
 *
 * returns 0 to indicate success
 * returns <0 to indicate failure
 */
int print_platforms() {
	struct platform_intf **_intf, *intf;
	const char **id;
	int rc;

	/* go through all supported interfaces */
	for (_intf = platform_intf_list; _intf && *_intf; _intf++) {
		intf = *_intf;

		if (intf->type == PLATFORM_DEFAULT)
			continue;

		for (id = intf->id_list; id && *id; id++) {
			struct kv_pair *kv;

			kv = kv_pair_new();
			kv_pair_add(kv, "id", *id);
			rc = kv_pair_print(kv);
			kv_pair_free(kv);
			if (rc)
				return rc;
		}
	}

	return rc;
}
