/*
 * Copyright (c) 2000-2003 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, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "libxfs.h"
#include <signal.h>
#include "command.h"
#include "input.h"
#include "output.h"
#include "sig.h"
#include "malloc.h"
#include "init.h"

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

int	inputstacksize;
FILE	**inputstack;
FILE	*curinput;

static void	popfile(void);
static int	source_f(int argc, char **argv);

static const cmdinfo_t	source_cmd =
	{ "source", NULL, source_f, 1, 1, 0, N_("source-file"),
	  N_("get commands from source-file"), NULL };

/* our homegrown strtok that understands strings */

static char *
tokenize(
	char        *inp)
{
	static char *last_place = NULL;
	char        *start;
	char        *walk;
	int         in_string = 0;
	int         in_escape = 0;

	if (inp) {
		start = inp;
	} else {
		if (last_place == NULL)
			return NULL;

		/* we're done */
		if (*last_place != '\0')
			return NULL;

		start = last_place + 1;
	}
	last_place = NULL;

	/* eat whitespace */
	while (*start == ' ' || *start == '\t')
		start++;

	walk = start;
	for (;*walk != '\0'; walk++) {
		if (in_escape) {
			in_escape = 0;
			continue;
		}
		if (*walk == '\\')
			in_escape = 1;
		else if (*walk == '\"')
			in_string ^= 1;

		if (!in_string && !in_escape &&
		    (*walk == ' ' || *walk == '\t')) {
			last_place = walk;
			*last_place = '\0';
			break;
		}
	}
	if (walk == start)
		return NULL;

	return start;
}

char **
breakline(
	char	*input,
	int	*count)
{
	int	c;
	char	*inp;
	char	*p;
	char	**rval;

	c = 0;
	inp = input;
	rval = xcalloc(sizeof(char *), 1);
	for (;;) {

		p = tokenize(inp);

		if (p == NULL)
			break;
		inp = NULL;
		c++;
		rval = xrealloc(rval, sizeof(*rval) * (c + 1));
		rval[c - 1] = p;
		rval[c] = NULL;
	}
	*count = c;
	return rval;
}

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

static char *
get_prompt(void)
{
	static char	prompt[FILENAME_MAX + 1];

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

static char *
fetchline_internal(void)
{
	char	buf[1024];
	int	iscont;
	size_t	len;
	size_t	rlen;
	char	*rval;

	rval = NULL;
	for (rlen = iscont = 0; ; ) {
		if (curinput == stdin) {
			if (iscont)
				dbprintf("... ");
			else
				dbprintf(get_prompt(), progname);
			fflush(stdin);
		}
		if (seenint() ||
		    (!fgets(buf, sizeof(buf), curinput) &&
		     ferror(curinput) && seenint())) {
			clearint();
			dbprintf("^C\n");
			clearerr(curinput);
			if (iscont) {
				iscont = 0;
				rlen = 0;
				if (rval) {
					xfree(rval);
					rval = NULL;
				}
			}
			continue;
		}
		if (ferror(curinput) || feof(curinput) ||
		    (len = strlen(buf)) == 0) {
			/*
			 * No more input at this inputstack level; pop
			 * our fd off and return so that a lower
			 * level fetchline can handle us.  If this was
			 * an interactive session, print a newline
			 * because ^D doesn't emit one.
			 */
			if (curinput == stdin)
				dbprintf("\n");

			popfile();
			iscont = 0;
			rlen = 0;
			if (rval) {
				xfree(rval);
				rval = NULL;
			}
			return NULL;
		}
		if (inputstacksize == 1)
			logprintf("%s", buf);
		rval = xrealloc(rval, rlen + len + 1);
		if (rlen == 0)
			rval[0] = '\0';
		rlen += len;
		strcat(rval, buf);
		if (buf[len - 1] == '\n') {
			if (len > 1 && buf[len - 2] == '\\') {
				rval[rlen - 2] = ' ';
				rval[rlen - 1] = '\0';
				rlen--;
				iscont = 1;
			} else {
				rval[rlen - 1] = '\0';
				rlen--;
				break;
			}
		}
	}
	return rval;
}

#ifdef ENABLE_READLINE
char *
fetchline(void)
{
	char	*line;

	if (inputstacksize == 1) {
		line = readline(get_prompt());
		if (!line)
			dbprintf("\n");
		else if (line && *line) {
			add_history(line);
			logprintf("%s", line);
		}
	} else {
		line = fetchline_internal();
	}
	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);
	}

	if (inputstacksize == 1) {
		line = xstrdup(el_gets(el, &count));
		if (line) {
			if (count > 0)
				line[count-1] = '\0';
			if (*line) {
				history(hist, &hevent, H_ENTER, line);
				logprintf("%s", line);
			}
		}
	} else {
		line = fetchline_internal();
	}
	return line;
}
#else
char * fetchline(void) { return fetchline_internal(); }
#endif

static void
popfile(void)
{
	if (inputstacksize == 0) {
		curinput = NULL;
		return;
	}
	if (curinput != stdin)
		fclose(curinput);

	inputstacksize--;
	if (inputstacksize) {
	    inputstack =
		    xrealloc(inputstack, inputstacksize * sizeof(*inputstack));
	    curinput = inputstack[inputstacksize - 1];
	} else {
	    free(inputstack);
	    curinput = NULL;
	    inputstack = NULL;
	}
}

void
pushfile(
	FILE	*file)
{
	inputstack =
		xrealloc(inputstack,
			(inputstacksize + 1) * sizeof(*inputstack));
	inputstacksize++;
	curinput = inputstack[inputstacksize - 1] = file;
}

/* ARGSUSED */
static int
source_f(
	int	argc,
	char	**argv)
{
	FILE	*f;
	int	c, done = 0;
	char	*input;
	char	**v;

	f = fopen(argv[1], "r");
	if (f == NULL) {
		dbprintf(_("can't open %s\n"), argv[0]);
		return 0;
	}

	/* Run the sourced commands now. */
	pushfile(f);
	while (!done) {
		if ((input = fetchline_internal()) == NULL)
			break;
		v = breakline(input, &c);
		if (c)
			done = command(c, v);
		doneline(input, v);
	}

	return 0;
}

void
input_init(void)
{
	add_command(&source_cmd);
}
