#include <stdio.h>

#include <common/cfgparse.h>
#include <proto/arg.h>
#include <proto/log.h>
#include <proto/sample.h>
#include <import/da.h>

static int da_json_file(char **args, int section_type, struct proxy *curpx,
                        struct proxy *defpx, const char *file, int line,
                        char **err)
{
	if (*(args[1]) == 0) {
		memprintf(err, "deviceatlas json file : expects a json path.\n");
		return -1;
	}
	global.deviceatlas.jsonpath = strdup(args[1]);
	return 0;
}

static int da_log_level(char **args, int section_type, struct proxy *curpx,
                        struct proxy *defpx, const char *file, int line,
                        char **err)
{
	int loglevel;
	if (*(args[1]) == 0) {
		memprintf(err, "deviceatlas log level : expects an integer argument.\n");
		return -1;
	}

	loglevel = atol(args[1]);
	if (loglevel < 0 || loglevel > 3) {
		memprintf(err, "deviceatlas log level : expects a log level between 0 and 3, %s given.\n", args[1]);
	} else {
		global.deviceatlas.loglevel = (da_severity_t)loglevel;
	}

	return 0;
}

static int da_property_separator(char **args, int section_type, struct proxy *curpx,
                                 struct proxy *defpx, const char *file, int line,
                                 char **err)
{
	if (*(args[1]) == 0) {
		memprintf(err, "deviceatlas property separator : expects a character argument.\n");
		return -1;
	}
	global.deviceatlas.separator = *args[1];
	return 0;
}

static size_t da_haproxy_read(void *ctx, size_t len, char *buf)
{
	return fread(buf, 1, len, ctx);
}

static da_status_t da_haproxy_seek(void *ctx, off_t off)
{
	return fseek(ctx, off, SEEK_SET) != -1 ? DA_OK : DA_SYS;
}

static void da_haproxy_log(da_severity_t severity, da_status_t status,
	const char *fmt, va_list args)
{
	if (global.deviceatlas.loglevel && severity <= global.deviceatlas.loglevel) {
		char logbuf[256];
		vsnprintf(logbuf, sizeof(logbuf), fmt, args);
		Warning("deviceatlas : %s.\n", logbuf);
	}
}

int init_deviceatlas(void)
{
	da_status_t status = DA_SYS;
	if (global.deviceatlas.jsonpath != 0) {
		FILE *jsonp;
		da_property_decl_t extraprops[] = {{0, 0}};
		size_t atlasimglen;
		da_status_t status;

		jsonp = fopen(global.deviceatlas.jsonpath, "r");
		if (jsonp == 0) {
			Alert("deviceatlas : '%s' json file has invalid path or is not readable.\n",
				global.deviceatlas.jsonpath);
			goto out;
		}

		da_init();
		da_seterrorfunc(da_haproxy_log);
		status = da_atlas_compile(jsonp, da_haproxy_read, da_haproxy_seek,
			&global.deviceatlas.atlasimgptr, &atlasimglen);
		fclose(jsonp);
		if (status != DA_OK) {
			Alert("deviceatlas : '%s' json file is invalid.\n",
				global.deviceatlas.jsonpath);
			goto out;
		}

		status = da_atlas_open(&global.deviceatlas.atlas, extraprops,
			global.deviceatlas.atlasimgptr, atlasimglen);

		if (status != DA_OK) {
			Alert("deviceatlas : data could not be compiled.\n");
			goto out;
		}

		global.deviceatlas.useragentid = da_atlas_header_evidence_id(&global.deviceatlas.atlas,
			"user-agent");

		fprintf(stdout, "Deviceatlas module loaded.\n");
	}

out:
	return status == DA_OK;
}

void deinit_deviceatlas(void)
{
	if (global.deviceatlas.jsonpath != 0) {
		free(global.deviceatlas.jsonpath);
	}

	if (global.deviceatlas.useragentid > 0) {
		da_atlas_close(&global.deviceatlas.atlas);
		free(global.deviceatlas.atlasimgptr);
	}

	da_fini();
}

static int da_haproxy(const struct arg *args, struct sample *smp, void *private)
{
	struct chunk *tmp;
	da_deviceinfo_t devinfo;
	da_propid_t prop, *pprop;
	da_type_t proptype;
	da_status_t status;
	const char *useragent, *propname;
	char useragentbuf[1024];
	int i;

	if (global.deviceatlas.useragentid == 0) {
		return 1;
	}

	tmp = get_trash_chunk();
	chunk_reset(tmp);

	i = smp->data.u.str.len > sizeof(useragentbuf) ? sizeof(useragentbuf) : smp->data.u.str.len;
	memcpy(useragentbuf, smp->data.u.str.str, i - 1);
	useragentbuf[i - 1] = 0;

	useragent = (const char *)useragentbuf;
	propname = (const char *)args[0].data.str.str;
	i = 0;

	status = da_search(&global.deviceatlas.atlas, &devinfo,
		global.deviceatlas.useragentid, useragent, 0);
	if (status != DA_OK) {
		return 0;
	}

	for (; propname != 0; i ++, propname = (const char *)args[i].data.str.str) {
		status = da_atlas_getpropid(&global.deviceatlas.atlas,
			propname, &prop);
		if (status != DA_OK) {
			chunk_appendf(tmp, "%c", global.deviceatlas.separator);
			continue;
		}
		pprop = &prop;
		da_atlas_getproptype(&global.deviceatlas.atlas, *pprop, &proptype);

		switch (proptype) {
			case DA_TYPE_BOOLEAN: {
				bool val;
				status = da_getpropboolean(&devinfo, *pprop, &val);
				if (status == DA_OK) {
					chunk_appendf(tmp, "%d", val);
				}
				break;
			}
			case DA_TYPE_INTEGER:
			case DA_TYPE_NUMBER: {
				long val;
				status = da_getpropinteger(&devinfo, *pprop, &val);
				if (status == DA_OK) {
					chunk_appendf(tmp, "%ld", val);
				}
				break;
			}
			case DA_TYPE_STRING: {
				const char *val;
				status = da_getpropstring(&devinfo, *pprop, &val);
				if (status == DA_OK) {
					chunk_appendf(tmp, "%s", val);
				}
				break;
			}
		    default:
			break;
		}

		chunk_appendf(tmp, "%c", global.deviceatlas.separator);
	}

	da_close(&devinfo);

	if (tmp->len) {
		--tmp->len;
		tmp->str[tmp->len] = 0;
	}

	smp->data.u.str.str = tmp->str;
	smp->data.u.str.len = strlen(tmp->str);

	return 1;
}

static struct cfg_kw_list dacfg_kws = {{ }, {
	{ CFG_GLOBAL, "deviceatlas-json-file",	  da_json_file },
	{ CFG_GLOBAL, "deviceatlas-log-level",	  da_log_level },
	{ CFG_GLOBAL, "deviceatlas-property-separator", da_property_separator },
	{ 0, NULL, NULL },
}};

/* Note: must not be declared <const> as its list will be overwritten */
static struct sample_conv_kw_list conv_kws = {ILH, {
	{ "da-csv", da_haproxy, ARG5(1,STR,STR,STR,STR,STR), NULL, SMP_T_STR, SMP_T_STR },
	{ NULL, NULL, 0, 0, 0 },
}};

__attribute__((constructor))
static void __da_init(void)
{
	/* register sample fetch and format conversion keywords */
	sample_register_convs(&conv_kws);
	cfg_register_keywords(&dacfg_kws);
}
