/*
 *  Main for evloop command line tool.
 *
 *  Runs a given script from file or stdin inside an eventloop.  The
 *  script can then access setTimeout() etc.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef NO_SIGNAL
#include <signal.h>
#endif

#include "duktape.h"

extern void poll_register(duk_context *ctx);
extern void ncurses_register(duk_context *ctx);
extern void socket_register(duk_context *ctx);
extern void fileio_register(duk_context *ctx);
extern void eventloop_register(duk_context *ctx);
extern int eventloop_run(duk_context *ctx);  /* Duktape/C function, safe called */

static int c_evloop = 0;

#ifndef NO_SIGNAL
static void my_sighandler(int x) {
	fprintf(stderr, "Got signal %d\n", x);
	fflush(stderr);
}
static void set_sigint_handler(void) {
	(void) signal(SIGINT, my_sighandler);
}
#endif  /* NO_SIGNAL */

/* Print error to stderr and pop error. */
static void print_error(duk_context *ctx, FILE *f) {
	if (duk_is_object(ctx, -1) && duk_has_prop_string(ctx, -1, "stack")) {
		/* XXX: print error objects specially */
		/* XXX: pcall the string coercion */
		duk_get_prop_string(ctx, -1, "stack");
		if (duk_is_string(ctx, -1)) {
			fprintf(f, "%s\n", duk_get_string(ctx, -1));
			fflush(f);
			duk_pop_2(ctx);
			return;
		} else {
			duk_pop(ctx);
		}
	}
	duk_to_string(ctx, -1);
	fprintf(f, "%s\n", duk_get_string(ctx, -1));
	fflush(f);
	duk_pop(ctx);
}

int wrapped_compile_execute(duk_context *ctx) {
	int comp_flags = 0;
	int rc;

	/* Compile input and place it into global _USERCODE */
	duk_compile(ctx, comp_flags);
	duk_push_global_object(ctx);
	duk_insert(ctx, -2);  /* [ ... global func ] */
	duk_put_prop_string(ctx, -2, "_USERCODE");
	duk_pop(ctx);
#if 0
	printf("compiled usercode\n");
#endif

	/* Start a zero timer which will call _USERCODE from within
	 * the event loop.
	 */
	fprintf(stderr, "set _USERCODE timer\n");
	fflush(stderr);
	duk_eval_string(ctx, "setTimeout(function() { _USERCODE(); }, 0);");
	duk_pop(ctx);

	/* Finally, launch eventloop.  This call only returns after the
	 * eventloop terminates.
	 */
	if (c_evloop) {
		fprintf(stderr, "calling eventloop_run()\n");
		fflush(stderr);
		rc = duk_safe_call(ctx, eventloop_run, 0 /*nargs*/, 1 /*nrets*/);
		if (rc != 0) {
			fprintf(stderr, "eventloop_run() failed: %s\n", duk_to_string(ctx, -1));
			fflush(stderr);
		}
		duk_pop(ctx);
	} else {
		fprintf(stderr, "calling EventLoop.run()\n");
		fflush(stderr);
		duk_eval_string(ctx, "EventLoop.run();");
		duk_pop(ctx);
	}

	return 0;
}

int handle_fh(duk_context *ctx, FILE *f, const char *filename) {
	char *buf = NULL;
	int len;
	int got;
	int rc;
	int retval = -1;

	if (fseek(f, 0, SEEK_END) < 0) {
		goto error;
	}
	len = (int) ftell(f);
	if (fseek(f, 0, SEEK_SET) < 0) {
		goto error;
	}
	buf = (char *) malloc(len);
	if (!buf) {
		goto error;
	}

	got = fread((void *) buf, (size_t) 1, (size_t) len, f);

	duk_push_lstring(ctx, buf, got);
	duk_push_string(ctx, filename);

	free(buf);
	buf = NULL;

	rc = duk_safe_call(ctx, wrapped_compile_execute, 2 /*nargs*/, 1 /*nret*/);
	if (rc != DUK_EXEC_SUCCESS) {
		print_error(ctx, stderr);
		goto error;
	} else {
		duk_pop(ctx);
		retval = 0;
	}
	/* fall thru */

 error:
	if (buf) {
		free(buf);
	}
	return retval;
}

int handle_file(duk_context *ctx, const char *filename) {
	FILE *f = NULL;
	int retval;

	f = fopen(filename, "rb");
	if (!f) {
		fprintf(stderr, "failed to open source file: %s\n", filename);
		fflush(stderr);
		goto error;
	}

	retval = handle_fh(ctx, f, filename);

	fclose(f);
	return retval;

 error:
	return -1;
}

int handle_stdin(duk_context *ctx) {
	int retval;

	retval = handle_fh(ctx, stdin, "stdin");

	return retval;
}

int main(int argc, char *argv[]) {
	duk_context *ctx = NULL;
	int retval = 0;
	const char *filename = NULL;
	int i;

#ifndef NO_SIGNAL
	set_sigint_handler();

	/* This is useful at the global level; libraries should avoid SIGPIPE though */
	/*signal(SIGPIPE, SIG_IGN);*/
#endif

	for (i = 1; i < argc; i++) {
		char *arg = argv[i];
		if (!arg) {
			goto usage;
		}
		if (strcmp(arg, "-c") == 0) {
			c_evloop = 1;
		} else if (strlen(arg) > 1 && arg[0] == '-') {
			goto usage;
		} else {
			if (filename) {
				goto usage;
			}
			filename = arg;
		}
	}
	if (!filename) {
		goto usage;
	}

	ctx = duk_create_heap_default();

	poll_register(ctx);
	ncurses_register(ctx);
	socket_register(ctx);
	fileio_register(ctx);

	if (c_evloop) {
		fprintf(stderr, "Using C based eventloop (omit -c to use Ecmascript based eventloop)\n");
		fflush(stderr);

		eventloop_register(ctx);
		duk_eval_file(ctx, "c_eventloop.js");
	} else {
		fprintf(stderr, "Using Ecmascript based eventloop (give -c to use C based eventloop)\n");
		fflush(stderr);

		duk_eval_file(ctx, "ecma_eventloop.js");
	}

	fprintf(stderr, "Executing code from: '%s'\n", filename);
	fflush(stderr);

	if (strcmp(filename, "-") == 0) {
		if (handle_stdin(ctx) != 0) {
			retval = 1;
			goto cleanup;
		}
	} else {
		if (handle_file(ctx, filename) != 0) {
			retval = 1;
			goto cleanup;
		}
	}

 cleanup:
	if (ctx) {
		duk_destroy_heap(ctx);
	}

	return retval;

 usage:
	fprintf(stderr, "Usage: evloop [-c] <filename>\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "Uses an Ecmascript based eventloop (ecma_eventloop.js) by default.\n");
	fprintf(stderr, "If -c option given, uses a C based eventloop (c_eventloop.{c,js}).\n");
	fprintf(stderr, "If <filename> is '-', the entire STDIN executed.\n");
	fflush(stderr);
	exit(1);
}
