/*
 * Copyright (C) 2013 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <stdio.h>
#include <ctype.h>
#include "if-main.h"
#include "terminal.h"

/* how many times tab was hit */
static int tab_hit_count;

typedef struct split_arg {
	struct split_arg *next; /* next argument in buffer */
	const char *origin; /* pointer to original argument */
	char ntcopy[1]; /* null terminated copy of argument */
} split_arg_t;

/* function returns method of given name or NULL if not found */
const struct method *get_interface_method(const char *iname,
							const char *mname)
{
	const struct interface *iface = get_interface(iname);

	if (iface == NULL)
		return NULL;

	return get_method(iface->methods, mname);
}

/* prints matching elements */
static void print_matches(enum_func f, void *user, const char *prefix, int len)
{
	int i;
	const char *enum_name;

	putchar('\n');
	for (i = 0; NULL != (enum_name = f(user, i)); ++i) {
		if (strncmp(enum_name, prefix, len) == 0)
			printf("%s\t", enum_name);
	}
	putchar('\n');
	terminal_draw_command_line();
}

/*
 * This function splits command line into linked list of arguments.
 * line_buffer - pointer to input command line
 * size - size of command line to parse
 * buf - output buffer to keep split arguments list
 * buf_size_in_bytes - size of buf
 */
static int split_command(const char *line_buffer, int size, split_arg_t *buf,
							int buf_size_in_bytes)
{
	split_arg_t *prev = NULL;
	split_arg_t *arg = buf;
	int argc = 0;
	const char *p = line_buffer;
	const char *e = p + (size > 0 ? size : (int) strlen(p));
	int len;

	do {
		while (p < e && isspace(*p))
			p++;
		arg->origin = p;
		arg->next = NULL;
		while (p < e && !isspace(*p))
			p++;
		len = p - arg->origin;
		if (&arg->ntcopy[0] + len + 1 >
			(const char *) buf + buf_size_in_bytes)
			break;
		strncpy(arg->ntcopy, arg->origin, len);
		arg->ntcopy[len] = 0;
		if (prev != NULL)
			prev->next = arg;
		prev = arg;
		arg += (2 * sizeof(*arg) + len) / sizeof(*arg);
		argc++;
	} while (p < e);

	return argc;
}

/* Function to enumerate method names */
static const char *methods_name(void *v, int i)
{
	const struct interface *iface = v;

	return iface->methods[i].name[0] ? iface->methods[i].name : NULL;
}

struct command_completion_args;
typedef void (*short_help)(struct command_completion_args *args);

struct command_completion_args {
	const split_arg_t *arg; /* list of arguments */
	const char *typed; /* last typed element */
	enum_func func; /* enumerating function */
	void *user; /* argument to enumerating function */
	short_help help; /* help function */
	const char *user_help; /* additional data (used by short_help) */
};

/*
 * complete command line
 */
static void tab_completion(struct command_completion_args *args)
{
	const char *name = args->typed;
	const int len = strlen(name);
	int i;
	int j;
	char prefix[128] = {0};
	int prefix_len = 0;
	int count = 0;
	const char *enum_name;

	for (i = 0; NULL != (enum_name = args->func(args->user, i)); ++i) {
		/* prefix does not match */
		if (strncmp(enum_name, name, len) != 0)
			continue;

		/* prefix matches first time */
		if (count++ == 0) {
			strcpy(prefix, enum_name);
			prefix_len = strlen(prefix);
			continue;
		}

		/*
		 * Prefix matches next time
		 * reduce prefix to common part
		 */
		for (j = 0; prefix[j] != 0
			&& prefix[j] == enum_name[j];)
			++j;
		prefix_len = j;
		prefix[j] = 0;
	}

	if (count == 0) {
		/* no matches */
		if (args->help != NULL)
			args->help(args);
		tab_hit_count = 0;
		return;
	}

	/* len == prefix_len => nothing new was added */
	if (len == prefix_len) {
		if (count != 1) {
			if (tab_hit_count == 1) {
				putchar('\a');
			} else if (tab_hit_count == 2 ||
					args->help == NULL) {
				print_matches(args->func,
						args->user, name, len);
			} else {
				args->help(args);
				tab_hit_count = 1;
			}
		} else if (count == 1) {
			/* nothing to add, exact match add space */
			terminal_insert_into_command_line(" ");
		}
	} else {
		/* new chars can be added from some interface name(s) */
		if (count == 1) {
			/* exact match, add space */
			prefix[prefix_len++] = ' ';
			prefix[prefix_len] = '\0';
		}

		terminal_insert_into_command_line(prefix + len);
		tab_hit_count = 0;
	}
}

/* interface completion */
static void command_completion(split_arg_t *arg)
{
	struct command_completion_args args = {
		.arg = arg,
		.typed = arg->ntcopy,
		.func = command_name
	};

	tab_completion(&args);
}

/* method completion */
static void method_completion(const struct interface *iface, split_arg_t *arg)
{
	struct command_completion_args args = {
		.arg = arg,
		.typed = arg->next->ntcopy,
		.func = methods_name,
		.user = (void *) iface
	};

	if (iface == NULL)
		return;

	tab_completion(&args);
}

static const char *bold = "\x1b[1m";
static const char *normal = "\x1b[0m";

static bool find_nth_argument(const char *str, int n, const char **s,
								const char **e)
{
	const char *p = str;
	int argc = 0;
	*e = NULL;

	while (p != NULL && *p != 0) {

		while (isspace(*p))
			++p;

		if (n == argc)
			*s = p;

		if (*p == '[') {
			p = strchr(p, ']');
			if (p != NULL)
				*e = ++p;
		} else if (*p == '<') {
			p = strchr(p, '>');
			if (p != NULL)
				*e = ++p;
		} else {
			*e = strchr(p, ' ');
			if (*e == NULL)
				*e = p + strlen(p);
			p = *e;
		}

		if (n == argc)
			break;

		argc++;
		*e = NULL;
	}
	return *e != NULL;
}

/* prints short help on method for interface */
static void method_help(struct command_completion_args *args)
{
	int argc;
	const split_arg_t *arg = args->arg;
	const char *sb = NULL;
	const char *eb = NULL;
	const char *arg1 = "";
	int arg1_size = 0; /* size of method field (for methods > 0) */

	if (args->user_help == NULL)
		return;

	for (argc = 0; arg != NULL; argc++)
		arg = arg->next;

	/* Check if this is method from interface */
	if (get_command(args->arg->ntcopy) == NULL) {
		/* if so help is missing interface and method name */
		arg1 = args->arg->next->ntcopy;
		arg1_size = strlen(arg1) + 1;
	}

	find_nth_argument(args->user_help, argc - (arg1_size ? 3 : 2),
								&sb, &eb);

	if (eb != NULL)
		haltest_info("%s %-*s%.*s%s%.*s%s%s\n", args->arg->ntcopy,
				arg1_size, arg1, (int) (sb - args->user_help),
				args->user_help, bold, (int) (eb - sb),
				sb, normal, eb);
	else
		haltest_info("%s %-*s%s\n", args->arg->ntcopy,
			arg1_size, arg1, args->user_help);
}

/* So we have empty enumeration */
static const char *return_null(void *user, int i)
{
	return NULL;
}

/*
 * parameter completion function
 * argc - number of elements in arg list
 * arg - list of arguments
 * method - method to get completion from (can be NULL)
 */
static void param_completion(int argc, const split_arg_t *arg,
					const struct method *method, int hlpix)
{
	int i;
	const char *argv[argc];
	const split_arg_t *tmp = arg;
	struct command_completion_args args = {
		.arg = arg,
		.func = return_null
	};

	/* prepare standard argv from arg */
	for (i = 0; i < argc; ++i) {
		argv[i] = tmp->ntcopy;
		tmp = tmp->next;
	}

	if (method != NULL && method->complete != NULL) {
		/* ask method for completion function */
		method->complete(argc, argv, &args.func, &args.user);
	}

	/* If method provided enumeration function call try to complete */
	if (args.func != NULL) {
		args.typed = argv[argc - 1];
		args.help = method_help;
		args.user_help = method ? method->help : NULL;

		tab_completion(&args);
	}
}

/*
 * This method gets called when user tapped tab key.
 * line - points to command line
 * len - size of line that should be used for completions. This should be
 *   cursor position during tab hit.
 */
void process_tab(const char *line, int len)
{
	int argc;
	static split_arg_t buf[(LINE_BUF_MAX * 2) / sizeof(split_arg_t)];
	const struct method *method;

	argc = split_command(line, len, buf, sizeof(buf));
	tab_hit_count++;

	if (argc == 0)
		return;

	if (argc == 1) {
		command_completion(buf);
		return;
	}

	method = get_command(buf[0].ntcopy);
	if (method != NULL) {
		param_completion(argc, buf, method, 1);
	} else if (argc == 2) {
		method_completion(get_interface(buf[0].ntcopy), buf);
	} else {
		/* Find method for <interface, name> pair */
		method = get_interface_method(buf[0].ntcopy,
							buf[0].next->ntcopy);
		param_completion(argc, buf, method, 2);
	}
}
