/*
 *  Example program using the dvalue debug transport.
 */

#include <stdio.h>
#include <stdlib.h>

#include "duktape.h"
#include "duk_trans_dvalue.h"

void my_cooperate(duk_trans_dvalue_ctx *ctx, int block) {
	static int first_blocked = 1;

	if (!block) {
		/* Duktape is not blocked; you can cooperate with e.g. a user
		 * interface here and send dvalues to Duktape, but don't block.
		 */
		return;
	}

	/* Duktape is blocked on a read and won't continue until debug
	 * command(s) are sent.
	 *
	 * Normally you'd enter your own event loop here, and process
	 * events until something needs to be sent to Duktape.  For
	 * example, the user might press a "Step over" button in the
	 * UI which would cause dvalues to be sent.  You can then
	 * return from this callback.
	 *
	 * The code below sends some example messages for testing the
	 * dvalue handling of the transport.
	 *
	 * If you create dvalues manually and send them using
	 * duk_trans_dvalue_send(), you must free the dvalues after
	 * the send call returns using duk_dvalue_free().
	 */

	if (first_blocked) {
		char *tmp;
		int i;

		/* First time Duktape becomes blocked, send DumpHeap which
		 * exercises a lot of parsing code.
		 *
		 * NOTE: Valgrind may complain about reading uninitialized
		 * bytes.  This is caused by the DumpHeap command writing out
		 * verbatim duk_tval values which are intentionally not
		 * always fully initialized for performance reasons.
		 */
		first_blocked = 0;

		fprintf(stderr, "Duktape is blocked, send DumpHeap\n");
		fflush(stderr);

		duk_trans_dvalue_send_req(ctx);
		duk_trans_dvalue_send_integer(ctx, 0x20);  /* DumpHeap */
		duk_trans_dvalue_send_eom(ctx);

		/* Also send a dummy TriggerStatus request with trailing dvalues
		 * ignored by Duktape; Duktape will parse the dvalues to be able to
		 * skip them, so that the dvalue encoding is exercised.
		 */

		tmp = malloc(100000);  /* long buffer, >= 65536 chars */
		for (i = 0; i < 100000; i++) {
			tmp[i] = (char) i;
		}
		duk_trans_dvalue_send_req(ctx);
		duk_trans_dvalue_send_integer(ctx, 0x11);  /* TriggerStatus */
		duk_trans_dvalue_send_string(ctx, "dummy");  /* short, <= 31 chars */
		duk_trans_dvalue_send_string(ctx, "123456789012345678901234567890foobar");  /* medium, >= 32 chars */
		duk_trans_dvalue_send_lstring(ctx, (const char *) tmp, 65535UL);
		duk_trans_dvalue_send_lstring(ctx, (const char *) tmp, 65536UL);
		duk_trans_dvalue_send_lstring(ctx, (const char *) tmp, 100000UL);
		duk_trans_dvalue_send_buffer(ctx, (const char *) tmp, 255U);
		duk_trans_dvalue_send_buffer(ctx, (const char *) tmp, 65535UL);
		duk_trans_dvalue_send_buffer(ctx, (const char *) tmp, 65536UL);
		duk_trans_dvalue_send_buffer(ctx, (const char *) tmp, 100000UL);
		duk_trans_dvalue_send_unused(ctx);
		duk_trans_dvalue_send_undefined(ctx);
		duk_trans_dvalue_send_null(ctx);
		duk_trans_dvalue_send_true(ctx);
		duk_trans_dvalue_send_false(ctx);
		duk_trans_dvalue_send_number(ctx, 123.456);
		duk_trans_dvalue_send_object(ctx, 12 /*classnum*/, (const char *) tmp, 8);  /* fake ptr len */
		duk_trans_dvalue_send_pointer(ctx, (const char *) tmp, 8);  /* fake ptr len */
		duk_trans_dvalue_send_lightfunc(ctx, 0xdabc /*lf_flags*/, (const char *) tmp, 8);  /* fake ptr len */
		duk_trans_dvalue_send_heapptr(ctx, (const char *) tmp, 8);  /* fake ptr len */

		duk_trans_dvalue_send_eom(ctx);
	}

	fprintf(stderr, "Duktape is blocked, send Eval and StepInto to resume execution\n");
	fflush(stderr);

	/* duk_trans_dvalue_send_req_cmd() sends a REQ dvalue followed by
	 * an integer dvalue (command) for convenience.
	 */

	duk_trans_dvalue_send_req_cmd(ctx, 0x1e);  /* 0x1e = Eval */
	duk_trans_dvalue_send_string(ctx, "evalMe");
	duk_trans_dvalue_send_eom(ctx);

	duk_trans_dvalue_send_req_cmd(ctx, 0x14);  /* 0x14 = StepOver */
	duk_trans_dvalue_send_eom(ctx);
}

void my_received(duk_trans_dvalue_ctx *ctx, duk_dvalue *dv) {
	char buf[DUK_DVALUE_TOSTRING_BUFLEN];
	(void) ctx;

	duk_dvalue_to_string(dv, buf);
	fprintf(stderr, "Received dvalue: %s\n", buf);
	fflush(stderr);

	/* Here a normal debug client would wait for dvalues until an EOM
	 * dvalue was received (which completes a debug message).  The
	 * debug message would then be handled, possibly causing UI changes
	 * and/or causing debug commands to be sent to Duktape.
	 *
	 * The callback is responsible for eventually freeing the dvalue.
	 * Here we free it immediately, but an actual client would probably
	 * gather dvalues into an array or linked list to handle when the
	 * debug message was complete.
	 */

	duk_dvalue_free(dv);
}

void my_handshake(duk_trans_dvalue_ctx *ctx, const char *line) {
	(void) ctx;

	/* The Duktape handshake line is given in 'line' (without LF).
	 * The 'line' argument can be accessed for the duration of the
	 * callback (read only).  Don't free 'line' here, the transport
	 * handles that.
	 */

	fprintf(stderr, "Received handshake line: '%s'\n", line);
	fflush(stderr);
}

void my_detached(duk_trans_dvalue_ctx *ctx) {
	(void) ctx;

	/* Detached call forwarded as is. */

	fprintf(stderr, "Debug transport detached\n");
	fflush(stderr);
}

int main(int argc, char *argv[]) {
	duk_context *ctx;
	duk_trans_dvalue_ctx *trans_ctx;
	int exitval = 0;

	(void) argc; (void) argv;  /* suppress warning */

	ctx = duk_create_heap_default();
	if (!ctx) {
		fprintf(stderr, "Failed to create Duktape heap\n");
		fflush(stderr);
		exitval = 1;
		goto cleanup;
	}

	trans_ctx = duk_trans_dvalue_init();
	if (!trans_ctx) {
		fprintf(stderr, "Failed to create debug transport context\n");
		fflush(stderr);
		exitval = 1;
		goto cleanup;
	}
	trans_ctx->cooperate = my_cooperate;
	trans_ctx->received = my_received;
	trans_ctx->handshake = my_handshake;
	trans_ctx->detached = my_detached;

	/* Attach debugger; this will fail with a fatal error here unless
	 * debugger support is compiled in.  To fail more gracefully, call
	 * this under a duk_safe_call() to catch the error.
	 */
	duk_debugger_attach(ctx,
	                    duk_trans_dvalue_read_cb,
	                    duk_trans_dvalue_write_cb,
	                    duk_trans_dvalue_peek_cb,
	                    duk_trans_dvalue_read_flush_cb,
	                    duk_trans_dvalue_write_flush_cb,
	                    duk_trans_dvalue_detached_cb,
	                    (void *) trans_ctx);

	fprintf(stderr, "Debugger attached, running eval\n");
	fflush(stderr);

	/* Evaluate simple test code, callbacks will "step over" until end.
	 *
	 * The test code here is just for exercising the debug transport.
	 * The 'evalMe' variable is evaluated (using debugger command Eval)
	 * before every step to force different dvalues to be carried over
	 * the transport.
	 */

	duk_eval_string(ctx,
		"var evalMe;\n"
		"\n"
		"print('Hello world!');\n"
		"[ undefined, null, true, false, 123, -123, 123.1, 0, -0, 1/0, 0/0, -1/0, \n"
		"  'foo', Duktape.Buffer('bar'), Duktape.Pointer('dummy'), Math.cos, \n"
		"].forEach(function (val) {\n"
		"    print(val);\n"
		"    evalMe = val;\n"
		"});\n"
		"\n"
		"var str = 'xxx'\n"
		"for (i = 0; i < 10; i++) {\n"
		"    print(i, str);\n"
		"    evalMe = str;\n"
		"    evalMe = Duktape.Buffer(str);\n"
		"    str = str + str;\n"
		"}\n"
	);
	duk_pop(ctx);

	duk_debugger_detach(ctx);

 cleanup:
	if (trans_ctx) {
		duk_trans_dvalue_free(trans_ctx);
		trans_ctx = NULL;
	}
	if (ctx) {
		duk_destroy_heap(ctx);
	}

	return exitval;
}
