#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

#include <libubus.h>
#include <libubox/blobmsg_json.h>
#include <libubox/blobmsg.h>

#include <json-validator.h>
#include <json-c/json.h>
#include <json-editor.h>

#include <json-c/json_tokener.h>
#include <easy/easy.h>
#include <qos.h>

#include <qosmngr.h>

struct test_ctx {
	struct blob_buf bb;
	struct ubus_object qos;
	FILE *fp;
};

/* declare qosmngr functions */
int qosmngr_event_main(const char *evmap_file);

/* overload ubus_send_reply to prevent segfault*/
int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req,
		    struct blob_attr *msg)
{
	return 0;
}


char *multi_tok(char *input, char *delimiter)
{
    static char *string;
	char *end, *temp;

    if (input)
        string = input;

    if (!string)
        return string;

    end = strstr(string, delimiter);

    if (!end) {
        char *temp = string;

        string = NULL;
        return temp;
    }

    temp = string;

    *end = '\0';
    string = end + strlen(delimiter);

    return temp;
}


/* TODO: how to fix events without fopen and fclose every poll? */
struct json_object *poll_test_log(FILE *fp, const char *prefix)
{
	char line[256] = {0};
	char msg[256] = {0};
	struct json_object *obj = NULL;

    fp = fopen("/tmp/test.log", "r");
    if (!fp) {
        return NULL;
    }

	while (fgets(line, 256, fp))  {
		char *ptr, *s;
		char appended[32];

		snprintf(appended, sizeof(appended), "%s:", prefix);

		ptr = strstr(line, appended);
		if (!ptr)
			continue;

		s = multi_tok(ptr, appended);
		s = multi_tok(NULL, appended);
		strncpy(msg, s, sizeof(msg));
	}

	if (strlen(msg))
		obj = json_tokener_parse(msg);

	fclose(fp);
	return obj;
}

static int group_setup(void **state)
{
	struct test_ctx *ctx = calloc(1, sizeof(struct test_ctx));

	if (!ctx)
		return -1;

	remove("/tmp/test.log");

	ctx->qos.name = "qos";

	memset(&ctx->bb, 0, sizeof(struct blob_buf));

	*state = ctx;
	return 0;
}

static int group_teardown(void **state)
{
	struct test_ctx *ctx = (struct test_ctx *) *state;

	blob_buf_free(&ctx->bb);
	free(ctx);
	remove("/tmp/test.log");

	/* TODO: fix event poll file */
	//if (ctx->fp)
		//fclose(ctx->fp);
	return 0;
}

int main(void)
{
	const struct CMUnitTest tests[] = {
	};

	return cmocka_run_group_tests(tests, group_setup, group_teardown);
}