/*
 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * 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.
 *
 * This program is distributed in the hope that it would 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, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/time.h>
#include <getopt.h>

#include "cmd.h"
#include "qemu-aio.h"
#include "main-loop.h"

#define _(x)	x	/* not gettext support yet */

/* from libxcmd/command.c */

cmdinfo_t	*cmdtab;
int		ncmds;

static argsfunc_t	args_func;
static checkfunc_t	check_func;
static int		ncmdline;
static char		**cmdline;

static int
compare(const void *a, const void *b)
{
	return strcmp(((const cmdinfo_t *)a)->name,
		      ((const cmdinfo_t *)b)->name);
}

void add_command(const cmdinfo_t *ci)
{
    cmdtab = g_realloc((void *)cmdtab, ++ncmds * sizeof(*cmdtab));
    cmdtab[ncmds - 1] = *ci;
    qsort(cmdtab, ncmds, sizeof(*cmdtab), compare);
}

static int
check_command(
	const cmdinfo_t	*ci)
{
	if (check_func)
		return check_func(ci);
	return 1;
}

void
add_check_command(
	checkfunc_t	cf)
{
	check_func = cf;
}

int
command_usage(
	const cmdinfo_t *ci)
{
	printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
	return 0;
}

int
command(
	const cmdinfo_t	*ct,
	int		argc,
	char		**argv)
{
	char		*cmd = argv[0];

	if (!check_command(ct))
		return 0;

	if (argc-1 < ct->argmin || (ct->argmax != -1 && argc-1 > ct->argmax)) {
		if (ct->argmax == -1)
			fprintf(stderr,
	_("bad argument count %d to %s, expected at least %d arguments\n"),
				argc-1, cmd, ct->argmin);
		else if (ct->argmin == ct->argmax)
			fprintf(stderr,
	_("bad argument count %d to %s, expected %d arguments\n"),
				argc-1, cmd, ct->argmin);
		else
			fprintf(stderr,
	_("bad argument count %d to %s, expected between %d and %d arguments\n"),
			argc-1, cmd, ct->argmin, ct->argmax);
		return 0;
	}
	optind = 0;
	return ct->cfunc(argc, argv);
}

const cmdinfo_t *
find_command(
	const char	*cmd)
{
	cmdinfo_t	*ct;

	for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
		if (strcmp(ct->name, cmd) == 0 ||
		    (ct->altname && strcmp(ct->altname, cmd) == 0))
			return (const cmdinfo_t *)ct;
	}
	return NULL;
}

void add_user_command(char *optarg)
{
    cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *));
    cmdline[ncmdline-1] = optarg;
}

static int
args_command(
	int	index)
{
	if (args_func)
		return args_func(index);
	return 0;
}

void
add_args_command(
	argsfunc_t	af)
{
	args_func = af;
}

static void prep_fetchline(void *opaque)
{
    int *fetchable = opaque;

    qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
    *fetchable= 1;
}

static char *get_prompt(void);

void command_loop(void)
{
    int c, i, j = 0, done = 0, fetchable = 0, prompted = 0;
    char *input;
    char **v;
    const cmdinfo_t *ct;

    for (i = 0; !done && i < ncmdline; i++) {
        input = strdup(cmdline[i]);
        if (!input) {
            fprintf(stderr, _("cannot strdup command '%s': %s\n"),
                    cmdline[i], strerror(errno));
            exit(1);
        }
        v = breakline(input, &c);
        if (c) {
            ct = find_command(v[0]);
            if (ct) {
                if (ct->flags & CMD_FLAG_GLOBAL) {
                    done = command(ct, c, v);
                } else {
                    j = 0;
                    while (!done && (j = args_command(j))) {
                        done = command(ct, c, v);
                    }
                }
            } else {
                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
            }
	}
        doneline(input, v);
    }
    if (cmdline) {
        g_free(cmdline);
        return;
    }

    while (!done) {
        if (!prompted) {
            printf("%s", get_prompt());
            fflush(stdout);
            qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
            prompted = 1;
        }

        main_loop_wait(false);

        if (!fetchable) {
            continue;
        }
        input = fetchline();
        if (input == NULL) {
            break;
        }
        v = breakline(input, &c);
        if (c) {
            ct = find_command(v[0]);
            if (ct) {
                done = command(ct, c, v);
            } else {
                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
            }
        }
        doneline(input, v);

        prompted = 0;
        fetchable = 0;
    }
    qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
}

/* from libxcmd/input.c */

#if defined(ENABLE_READLINE)
# include <readline/history.h>
# include <readline/readline.h>
#elif defined(ENABLE_EDITLINE)
# include <histedit.h>
#endif

static char *
get_prompt(void)
{
	static char	prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];

	if (!prompt[0])
		snprintf(prompt, sizeof(prompt), "%s> ", progname);
	return prompt;
}

#if defined(ENABLE_READLINE)
char *
fetchline(void)
{
	char	*line;

	line = readline(get_prompt());
	if (line && *line)
		add_history(line);
	return line;
}
#elif defined(ENABLE_EDITLINE)
static char *el_get_prompt(EditLine *e) { return get_prompt(); }
char *
fetchline(void)
{
	static EditLine	*el;
	static History	*hist;
	HistEvent	hevent;
	char		*line;
	int		count;

	if (!el) {
		hist = history_init();
		history(hist, &hevent, H_SETSIZE, 100);
		el = el_init(progname, stdin, stdout, stderr);
		el_source(el, NULL);
		el_set(el, EL_SIGNAL, 1);
		el_set(el, EL_PROMPT, el_get_prompt);
		el_set(el, EL_HIST, history, (const char *)hist);
	}
	line = strdup(el_gets(el, &count));
	if (line) {
		if (count > 0)
			line[count-1] = '\0';
		if (*line)
			history(hist, &hevent, H_ENTER, line);
	}
	return line;
}
#else
# define MAXREADLINESZ	1024
char *
fetchline(void)
{
	char	*p, *line = malloc(MAXREADLINESZ);

	if (!line)
		return NULL;
	if (!fgets(line, MAXREADLINESZ, stdin)) {
		free(line);
		return NULL;
	}
	p = line + strlen(line);
	if (p != line && p[-1] == '\n')
		p[-1] = '\0';
	return line;
}
#endif

static char *qemu_strsep(char **input, const char *delim)
{
    char *result = *input;
    if (result != NULL) {
        char *p;

        for (p = result; *p != '\0'; p++) {
            if (strchr(delim, *p)) {
                break;
            }
        }
        if (*p == '\0') {
            *input = NULL;
        } else {
            *p = '\0';
            *input = p + 1;
        }
    }
    return result;
}

char **breakline(char *input, int *count)
{
    int c = 0;
    char *p;
    char **rval = calloc(sizeof(char *), 1);
    char **tmp;

    while (rval && (p = qemu_strsep(&input, " ")) != NULL) {
        if (!*p) {
            continue;
        }
        c++;
        tmp = realloc(rval, sizeof(*rval) * (c + 1));
        if (!tmp) {
            free(rval);
            rval = NULL;
            c = 0;
            break;
        } else {
            rval = tmp;
        }
        rval[c - 1] = p;
        rval[c] = NULL;
    }
    *count = c;
    return rval;
}

void
doneline(
	char	*input,
	char	**vec)
{
	free(input);
	free(vec);
}

#define EXABYTES(x)	((long long)(x) << 60)
#define PETABYTES(x)	((long long)(x) << 50)
#define TERABYTES(x)	((long long)(x) << 40)
#define GIGABYTES(x)	((long long)(x) << 30)
#define MEGABYTES(x)	((long long)(x) << 20)
#define KILOBYTES(x)	((long long)(x) << 10)

long long
cvtnum(
	char		*s)
{
	long long	i;
	char		*sp;
	int		c;

	i = strtoll(s, &sp, 0);
	if (i == 0 && sp == s)
		return -1LL;
	if (*sp == '\0')
		return i;

	if (sp[1] != '\0')
		return -1LL;

	c = qemu_tolower(*sp);
	switch (c) {
	default:
		return i;
	case 'k':
		return KILOBYTES(i);
	case 'm':
		return MEGABYTES(i);
	case 'g':
		return GIGABYTES(i);
	case 't':
		return TERABYTES(i);
	case 'p':
		return PETABYTES(i);
	case 'e':
		return  EXABYTES(i);
	}
	return -1LL;
}

#define TO_EXABYTES(x)	((x) / EXABYTES(1))
#define TO_PETABYTES(x)	((x) / PETABYTES(1))
#define TO_TERABYTES(x)	((x) / TERABYTES(1))
#define TO_GIGABYTES(x)	((x) / GIGABYTES(1))
#define TO_MEGABYTES(x)	((x) / MEGABYTES(1))
#define TO_KILOBYTES(x)	((x) / KILOBYTES(1))

void
cvtstr(
	double		value,
	char		*str,
	size_t		size)
{
	char		*trim;
	const char	*suffix;

	if (value >= EXABYTES(1)) {
		suffix = " EiB";
		snprintf(str, size - 4, "%.3f", TO_EXABYTES(value));
	} else if (value >= PETABYTES(1)) {
		suffix = " PiB";
		snprintf(str, size - 4, "%.3f", TO_PETABYTES(value));
	} else if (value >= TERABYTES(1)) {
		suffix = " TiB";
		snprintf(str, size - 4, "%.3f", TO_TERABYTES(value));
	} else if (value >= GIGABYTES(1)) {
		suffix = " GiB";
		snprintf(str, size - 4, "%.3f", TO_GIGABYTES(value));
	} else if (value >= MEGABYTES(1)) {
		suffix = " MiB";
		snprintf(str, size - 4, "%.3f", TO_MEGABYTES(value));
	} else if (value >= KILOBYTES(1)) {
		suffix = " KiB";
		snprintf(str, size - 4, "%.3f", TO_KILOBYTES(value));
	} else {
		suffix = " bytes";
		snprintf(str, size - 6, "%f", value);
	}

	trim = strstr(str, ".000");
	if (trim) {
		strcpy(trim, suffix);
	} else {
		strcat(str, suffix);
	}
}

struct timeval
tsub(struct timeval t1, struct timeval t2)
{
	t1.tv_usec -= t2.tv_usec;
	if (t1.tv_usec < 0) {
		t1.tv_usec += 1000000;
		t1.tv_sec--;
	}
	t1.tv_sec -= t2.tv_sec;
	return t1;
}

double
tdiv(double value, struct timeval tv)
{
	return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
}

#define HOURS(sec)	((sec) / (60 * 60))
#define MINUTES(sec)	(((sec) % (60 * 60)) / 60)
#define SECONDS(sec)	((sec) % 60)

void
timestr(
	struct timeval	*tv,
	char		*ts,
	size_t		size,
	int		format)
{
	double		usec = (double)tv->tv_usec / 1000000.0;

	if (format & TERSE_FIXED_TIME) {
		if (!HOURS(tv->tv_sec)) {
			snprintf(ts, size, "%u:%02u.%02u",
				(unsigned int) MINUTES(tv->tv_sec),
				(unsigned int) SECONDS(tv->tv_sec),
				(unsigned int) (usec * 100));
			return;
		}
		format |= VERBOSE_FIXED_TIME;	/* fallback if hours needed */
	}

	if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
		snprintf(ts, size, "%u:%02u:%02u.%02u",
			(unsigned int) HOURS(tv->tv_sec),
			(unsigned int) MINUTES(tv->tv_sec),
			(unsigned int) SECONDS(tv->tv_sec),
			(unsigned int) (usec * 100));
	} else {
		snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
	}
}


/* from libxcmd/quit.c */

static cmdinfo_t quit_cmd;

/* ARGSUSED */
static int
quit_f(
	int	argc,
	char	**argv)
{
	return 1;
}

void
quit_init(void)
{
	quit_cmd.name = _("quit");
	quit_cmd.altname = _("q");
	quit_cmd.cfunc = quit_f;
	quit_cmd.argmin = -1;
	quit_cmd.argmax = -1;
	quit_cmd.flags = CMD_FLAG_GLOBAL;
	quit_cmd.oneline = _("exit the program");

	add_command(&quit_cmd);
}

/* from libxcmd/help.c */

static cmdinfo_t help_cmd;
static void help_onecmd(const char *cmd, const cmdinfo_t *ct);
static void help_oneline(const char *cmd, const cmdinfo_t *ct);

static void
help_all(void)
{
	const cmdinfo_t	*ct;

	for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++)
		help_oneline(ct->name, ct);
	printf(_("\nUse 'help commandname' for extended help.\n"));
}

static int
help_f(
	int		argc,
	char		**argv)
{
	const cmdinfo_t	*ct;

	if (argc == 1) {
		help_all();
		return 0;
	}
	ct = find_command(argv[1]);
	if (ct == NULL) {
		printf(_("command %s not found\n"), argv[1]);
		return 0;
	}
	help_onecmd(argv[1], ct);
	return 0;
}

static void
help_onecmd(
	const char	*cmd,
	const cmdinfo_t	*ct)
{
	help_oneline(cmd, ct);
	if (ct->help)
		ct->help();
}

static void
help_oneline(
	const char	*cmd,
	const cmdinfo_t	*ct)
{
	if (cmd)
		printf("%s ", cmd);
	else {
		printf("%s ", ct->name);
		if (ct->altname)
			printf("(or %s) ", ct->altname);
	}
	if (ct->args)
		printf("%s ", ct->args);
	printf("-- %s\n", ct->oneline);
}

void
help_init(void)
{
	help_cmd.name = _("help");
	help_cmd.altname = _("?");
	help_cmd.cfunc = help_f;
	help_cmd.argmin = 0;
	help_cmd.argmax = 1;
	help_cmd.flags = CMD_FLAG_GLOBAL;
	help_cmd.args = _("[command]");
	help_cmd.oneline = _("help for one or all commands");

	add_command(&help_cmd);
}
