/*
 * Copyright (c) 2018-2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <stdlib.h>
#include "tp.h"
#include "tp_priv.h"
#include "ipv4.h"
#include "ipv6.h"
#include "udp_internal.h"

static sys_slist_t tp_mem = SYS_SLIST_STATIC_INIT(&tp_mem);
static sys_slist_t tp_nbufs = SYS_SLIST_STATIC_INIT(&tp_nbufs);
static sys_slist_t tp_pkts = SYS_SLIST_STATIC_INIT(&tp_pkts);
static sys_slist_t tp_seq = SYS_SLIST_STATIC_INIT(&tp_seq);

bool tp_trace;
enum tp_type tp_state = TP_NONE;

char *tp_basename(char *path)
{
	char *filename = strrchr(path, '/');

	return filename ? (filename + 1) : path;
}

size_t tp_str_to_hex(void *buf, size_t bufsize, const char *s)
{
	size_t i, j, len = strlen(s);

	tp_assert((len % 2) == 0, "Invalid string: %s", s);

	for (i = 0, j = 0; i < len; i += 2, j++) {

		uint8_t byte = (s[i] - '0') << 4 | (s[i + 1] - '0');

		((uint8_t *) buf)[j] = byte;
	}

	return j;
}

void *tp_malloc(size_t size, const char *file, int line, const char *func)
{
	struct tp_mem *mem = k_malloc(sizeof(struct tp_mem) + size +
					sizeof(*mem->footer));

	mem->file = file;
	mem->line = line;
	mem->func = func;

	mem->size = size;

	mem->header = TP_MEM_HEADER_COOKIE;

	mem->footer = (void *) ((uint8_t *) &mem->mem + size);
	*mem->footer = TP_MEM_FOOTER_COOKIE;

	sys_slist_append(&tp_mem, (sys_snode_t *) mem);

	return &mem->mem;
}

static void dump(void *data, size_t len)
{
	uint8_t *buf = data;
	size_t i, width = 8;

	for (i = 0; i < len; i++) {

		if ((i % width) == 0) {
			printk("0x%08lx\t", POINTER_TO_INT(buf + i));
		}

		printk("%02x ", buf[i]);

		if (((i + 1) % width) == 0 || i == (len - 1)) {
			printk("\n");
		}
	}
}

void tp_mem_chk(struct tp_mem *mem)
{
	if (mem->header != TP_MEM_HEADER_COOKIE ||
		*mem->footer != TP_MEM_FOOTER_COOKIE) {

		tp_dbg("%s:%d %s() %p size: %zu",
			mem->file, mem->line, mem->func, mem->mem, mem->size);

		dump(&mem->header, sizeof(mem->header));
		dump(mem->mem, mem->size);
		dump(mem->footer, sizeof(*mem->footer));

		tp_assert(mem->header == TP_MEM_HEADER_COOKIE,
				"%s:%d %s() %p Corrupt header cookie: 0x%x",
				mem->file, mem->line, mem->func, mem->mem,
				mem->header);

		tp_assert(*mem->footer == TP_MEM_FOOTER_COOKIE,
				"%s:%d %s() %p Corrupt footer cookie: 0x%x",
				mem->file, mem->line, mem->func, mem->mem,
				*mem->footer);
	}
}

void tp_free(void *ptr, const char *file, int line, const char *func)
{
	struct tp_mem *mem = (void *)((uint8_t *) ptr - sizeof(struct tp_mem));

	tp_mem_chk(mem);

	if (!sys_slist_find_and_remove(&tp_mem, (sys_snode_t *) mem)) {
		tp_assert(false, "%s:%d %s() Invalid free(%p)",
				file, line, func, ptr);
	}

	memset(mem, 0, sizeof(tp_mem) + mem->size + sizeof(*mem->footer));
	k_free(mem);
}

void *tp_calloc(size_t nmemb, size_t size, const char *file, int line,
		const char *func)
{
	size_t bytes = size * nmemb;
	void *ptr = tp_malloc(bytes, file, line, func);

	memset(ptr, 0, bytes);

	return ptr;
}

void tp_mem_stat(void)
{
	struct tp_mem *mem;

	SYS_SLIST_FOR_EACH_CONTAINER(&tp_mem, mem, next) {
		tp_dbg("len=%zu %s:%d", mem->size, mem->file, mem->line);
		tp_mem_chk(mem);
	}
}

struct net_buf *tp_nbuf_alloc(struct net_buf_pool *pool, size_t len,
				const char *file, int line, const char *func)
{
	struct net_buf *nbuf = net_buf_alloc_len(pool, len, K_NO_WAIT);
	struct tp_nbuf *tp_nbuf = k_malloc(sizeof(struct tp_nbuf));

	tp_assert(len, "");
	tp_assert(nbuf, "Out of nbufs");

	tp_dbg("size=%d %p %s:%d %s()", nbuf->size, nbuf, file, line, func);

	tp_nbuf->nbuf = nbuf;
	tp_nbuf->file = file;
	tp_nbuf->line = line;

	sys_slist_append(&tp_nbufs, (sys_snode_t *) tp_nbuf);

	return nbuf;
}

struct net_buf *tp_nbuf_clone(struct net_buf *buf, const char *file, int line,
				const char *func)
{
	struct net_buf *clone = net_buf_clone(buf, K_NO_WAIT);
	struct tp_nbuf *tb = k_malloc(sizeof(struct tp_nbuf));

	tp_dbg("size=%d %p %s:%d %s()", clone->size, clone, file, line, func);

	tb->nbuf = clone;
	tb->file = file;
	tb->line = line;

	sys_slist_append(&tp_nbufs, &tb->next);

	return clone;

}

void tp_nbuf_unref(struct net_buf *nbuf, const char *file, int line,
			const char *func)
{
	bool found = false;
	struct tp_nbuf *tp_nbuf;

	tp_dbg("len=%d %p %s:%d %s()", nbuf->len, nbuf, file, line, func);

	SYS_SLIST_FOR_EACH_CONTAINER(&tp_nbufs, tp_nbuf, next) {
		if (tp_nbuf->nbuf == nbuf) {
			found = true;
			break;
		}
	}

	tp_assert(found, "Invalid %s(%p): %s:%d", __func__, nbuf, file, line);

	sys_slist_find_and_remove(&tp_nbufs, (sys_snode_t *) tp_nbuf);

	net_buf_unref(nbuf);

	k_free(tp_nbuf);
}

void tp_nbuf_stat(void)
{
	struct tp_nbuf *tp_nbuf;

	SYS_SLIST_FOR_EACH_CONTAINER(&tp_nbufs, tp_nbuf, next) {
		tp_dbg("%s:%d len=%d", tp_nbuf->file, tp_nbuf->line,
			tp_nbuf->nbuf->len);
	}
}

void tp_pkt_alloc(struct net_pkt *pkt,
		  const char *file, int line)
{
	struct tp_pkt *tp_pkt = k_malloc(sizeof(struct tp_pkt));

	tp_assert(tp_pkt, "");
	tp_assert(pkt, "");

	tp_pkt->pkt = pkt;
	tp_pkt->file = file;
	tp_pkt->line = line;

	sys_slist_append(&tp_pkts, (sys_snode_t *) tp_pkt);
}

struct net_pkt *tp_pkt_clone(struct net_pkt *pkt, const char *file, int line)
{
	struct tp_pkt *tp_pkt = k_malloc(sizeof(struct tp_pkt));

	pkt = net_pkt_clone(pkt, K_NO_WAIT);

	tp_pkt->pkt = pkt;
	tp_pkt->file = file;
	tp_pkt->line = line;

	sys_slist_append(&tp_pkts, (sys_snode_t *) tp_pkt);

	return pkt;
}

void tp_pkt_unref(struct net_pkt *pkt, const char *file, int line)
{
	bool found = false;
	struct tp_pkt *tp_pkt;

	SYS_SLIST_FOR_EACH_CONTAINER(&tp_pkts, tp_pkt, next) {
		if (tp_pkt->pkt == pkt) {
			found = true;
			break;
		}
	}

	tp_assert(found, "Invalid %s(%p): %s:%d", __func__, pkt, file, line);

	sys_slist_find_and_remove(&tp_pkts, (sys_snode_t *) tp_pkt);

	net_pkt_unref(tp_pkt->pkt);

	k_free(tp_pkt);
}

void tp_pkt_stat(void)
{
	struct tp_pkt *pkt;

	SYS_SLIST_FOR_EACH_CONTAINER(&tp_pkts, pkt, next) {
		tp_dbg("%s:%d %p", pkt->file, pkt->line, pkt->pkt);
	}
}

#define tp_seq_dump(_seq)						\
{									\
	tp_dbg("%s %u->%u (%s%d) %s:%d %s() %s",			\
		(_seq)->kind == TP_SEQ ? "SEQ" : "ACK",			\
		(_seq)->old_value, (_seq)->value,			\
		(_seq)->req >= 0 ? "+" : "", (_seq)->req,		\
		(_seq)->file, (_seq)->line, (_seq)->func,		\
		(_seq)->of ? "OF" : "");				\
}

uint32_t tp_seq_track(int kind, uint32_t *pvalue, int req,
			const char *file, int line, const char *func)
{
	struct tp_seq *seq = k_calloc(1, sizeof(struct tp_seq));

	seq->file = file;
	seq->line = line;
	seq->func = func;

	seq->kind = kind;

	seq->req = req;
	seq->old_value = *pvalue;

	if (req > 0) {
		seq->of = __builtin_uadd_overflow(seq->old_value, seq->req,
							&seq->value);
	} else {
		seq->value += req;
	}

	*pvalue = seq->value;

	sys_slist_append(&tp_seq, (sys_snode_t *) seq);

	tp_seq_dump(seq);

	return seq->value;
}

void tp_seq_stat(void)
{
	struct tp_seq *seq;

	while ((seq = (struct tp_seq *) sys_slist_get(&tp_seq))) {
		tp_seq_dump(seq);
		k_free(seq);
	}
}

enum tp_type tp_msg_to_type(const char *s)
{
	enum tp_type type = TP_NONE;

#define is_tp(_s, _type) do {		\
	if (is(#_type, _s)) {		\
		type = _type;		\
		goto out;		\
	}				\
} while (0)

	is_tp(s, TP_COMMAND);
	is_tp(s, TP_CONFIG_REQUEST);
	is_tp(s, TP_INTROSPECT_REQUEST);
	is_tp(s, TP_DEBUG_STOP);
	is_tp(s, TP_DEBUG_STEP);
	is_tp(s, TP_DEBUG_CONTINUE);

#undef is_tp

out:
	tp_assert(type != TP_NONE, "Invalid message: %s", s);

	return type;
}

static void udp_finalize_pkt(struct net_pkt *pkt)
{
	int ret = 0;

	net_pkt_cursor_init(pkt);

	if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
		ret = net_ipv4_finalize(pkt, IPPROTO_UDP);
	}

	if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
		ret = net_ipv6_finalize(pkt, IPPROTO_UDP);
	}

	NET_ASSERT(ret == 0);
}

static int ip_header_add(struct net_pkt *pkt)
{
	if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
		struct in_addr src;
		struct in_addr dst;

		net_addr_pton(AF_INET, CONFIG_NET_CONFIG_MY_IPV4_ADDR, &src);
		net_addr_pton(AF_INET, CONFIG_NET_CONFIG_PEER_IPV4_ADDR, &dst);

		return net_ipv4_create(pkt, &src, &dst);
	}

	if (IS_ENABLED(CONFIG_NET_IPV6) && net_pkt_family(pkt) == AF_INET6) {
		struct in6_addr src;
		struct in6_addr dst;

		net_addr_pton(AF_INET6, CONFIG_NET_CONFIG_MY_IPV6_ADDR, &src);
		net_addr_pton(AF_INET6, CONFIG_NET_CONFIG_PEER_IPV6_ADDR, &dst);

		return net_ipv6_create(pkt, &src, &dst);
	}

	return -EINVAL;
}

static void tp_pkt_send(struct net_pkt *pkt)
{
	net_pkt_ref(pkt);

	if (net_send_data(pkt) < 0) {
		tp_err("net_send_data()");
	}

	tp_pkt_unref(pkt, tp_basename(__FILE__), __LINE__);
}

static struct net_pkt *tp_output_pkt_alloc(sa_family_t af,
					   struct net_if *iface,
					   size_t len,
					   const char *file, int line)
{
	struct tp_pkt *tp_pkt = k_malloc(sizeof(struct tp_pkt));

	tp_assert(tp_pkt, "");

	tp_pkt->pkt = net_pkt_alloc_with_buffer(iface,
					sizeof(struct net_udp_hdr) + len,
					af, IPPROTO_UDP, K_NO_WAIT);
	tp_assert(tp_pkt->pkt, "");

	tp_pkt->file = file;
	tp_pkt->line = line;

	sys_slist_append(&tp_pkts, (sys_snode_t *) tp_pkt);

	return tp_pkt->pkt;
}

void _tp_output(sa_family_t af, struct net_if *iface, void *data,
		size_t data_len, const char *file, int line)
{
	struct net_pkt *pkt = tp_output_pkt_alloc(af, iface, data_len,
						  file, line);
	int ret;

	ret = ip_header_add(pkt);
	if (ret < 0) {
		goto fail;
	}

	ret = net_udp_create(pkt, htons(4242), htons(4242));
	if (ret < 0) {
		goto fail;
	}

	ret = net_pkt_write(pkt, data, data_len);
	if (ret < 0) {
		goto fail;
	}

	udp_finalize_pkt(pkt);

	NET_ASSERT(net_pkt_get_len(pkt) <= net_if_get_mtu(pkt->iface));

	tp_pkt_send(pkt);

	return;
fail:
	NET_ASSERT(false);
}

struct tp *json_to_tp(void *data, size_t data_len)
{
	static struct tp tp;

	memset(&tp, 0, sizeof(tp));

	if (json_obj_parse(data, data_len, tp_descr, ARRAY_SIZE(tp_descr),
			&tp) < 0) {
		tp_err("json_obj_parse()");
	}

	tp.type = tp_msg_to_type(tp.msg);

	return &tp;
}

void tp_new_find_and_apply(struct tp_new *tp, const char *key, void *value,
				int type)
{
	bool found = false;
	int i;

	for (i = 0; i < tp->num_entries; i++) {
		if (is(key, tp->data[i].key)) {
			found = true;
			break;
		}
	}

	if (found) {
		switch (type) {
		case TP_BOOL: {
			bool new_value, old = *((bool *) value);

			new_value = atoi(tp->data[i].value);
			*((bool *) value) = new_value;
			tp_dbg("%s %d->%d", key, old, new_value);
			break;
		}
		case TP_INT: {
			int new_value, old_value = *((int *) value);

			new_value = atoi(tp->data[i].value);
			*((int *) value) = new_value;
			tp_dbg("%s %d->%d", key, old_value, new_value);
			break;
		}
		default:
			tp_err("Unimplemented");
		}
	}
}

enum tp_type json_decode_msg(void *data, size_t data_len)
{
	int decoded;
	struct tp_msg tp;

	memset(&tp, 0, sizeof(tp));

	decoded = json_obj_parse(data, data_len, tp_msg_dsc,
					ARRAY_SIZE(tp_msg_dsc), &tp);
#if 0
	if ((decoded & 1) == false) { /* TODO: this fails, why? */
		tp_err("json_obj_parse()");
	}
#endif
	tp_dbg("%s", tp.msg);

	return tp.msg ? tp_msg_to_type(tp.msg) : TP_NONE;
}

struct tp_new *json_to_tp_new(void *data, size_t data_len)
{
	static struct tp_new tp;
	int i;

	memset(&tp, 0, sizeof(tp));

	if (json_obj_parse(data, data_len, tp_new_dsc, ARRAY_SIZE(tp_new_dsc),
				&tp) < 0) {
		tp_err("json_obj_parse()");
	}

	tp_dbg("%s", tp.msg);

	for (i = 0; i < tp.num_entries; i++) {
		tp_dbg("%s=%s", tp.data[i].key, tp.data[i].value);
	}

	return &tp;
}

void tp_encode(struct tp *tp, void *data, size_t *data_len)
{
	int error;

	error = json_obj_encode_buf(tp_descr, ARRAY_SIZE(tp_descr), tp,
					data, *data_len);
	if (error) {
		tp_err("json_obj_encode_buf()");
	}

	*data_len = error ? 0 : strlen(data);
}


void tp_new_to_json(struct tp_new *tp, void *data, size_t *data_len)
{
	int error = json_obj_encode_buf(tp_new_dsc, ARRAY_SIZE(tp_new_dsc), tp,
					data, *data_len);
	if (error) {
		tp_err("json_obj_encode_buf()");
	}

	*data_len = error ? 0 : strlen(data);
}

void tp_out(sa_family_t af, struct net_if *iface, const char *msg,
	    const char *key, const char *value)
{
	if (tp_trace) {
		size_t json_len;
		static uint8_t buf[128]; /* TODO: Merge all static buffers and
				       * eventually drop them
				       */
		struct tp_new tp = {
			.msg = msg,
			.data = { { .key = key, .value = value } },
			.num_entries = 1
		};
		json_len = sizeof(buf);
		tp_new_to_json(&tp, buf, &json_len);
		if (json_len) {
			tp_output(af, iface, buf, json_len);
		}
	}
}

bool tp_tap_input(struct net_pkt *pkt)
{
	bool tap = tp_state != TP_NONE;

	if (tap) {
		net_pkt_ref(pkt);
		/* STAILQ_INSERT_HEAD(&tp_q, pkt, stq_next); */
	}

	return tap;
}
