/*
 * Copyright (c) 2017 Intel Corporation.
 * Copyright (c) 2017 Linaro Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define SYS_LOG_DOMAIN "irc"
#define SYS_LOG_LEVEL SYS_LOG_LEVEL_INFO
#include <logging/sys_log.h>

#include <board.h>
#include <random/rand32.h>
#include <errno.h>
#include <gpio.h>
#include <net/net_app.h>
#include <stdio.h>
#include <zephyr.h>
#include <net/dns_resolve.h>

#if !defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4)
#error "CONFIG_NET_IPV6 or CONFIG_NET_IPV4 must be enabled for irc_bot"
#endif

#define APP_BANNER "Zephyr IRC bot sample"

static void on_msg_rcvd(char *chan_name, char *umask, char *msg);

#define CMD_BUFFER_SIZE 256
static u8_t cmd_buf[CMD_BUFFER_SIZE];
static u16_t cmd_len;

#define NICK_BUFFER_SIZE 16
static char nick_buf[NICK_BUFFER_SIZE];

/* LED */
#if defined(LED0_GPIO_PORT)
#define LED_GPIO_NAME LED0_GPIO_PORT
#define LED_PIN LED0_GPIO_PIN
#else
#define LED_GPIO_NAME "(fail)"
#define LED_PIN 0
#endif

static struct device *led0;
static bool fake_led;

/* Network Config */
#define WAIT_TIMEOUT		K_SECONDS(10)
#define CONNECT_TIMEOUT		K_SECONDS(10)
#define BUF_ALLOC_TIMEOUT	K_SECONDS(1)

/* IRC API */
#define DEFAULT_SERVER	"irc.freenode.net"
#define DEFAULT_PORT	6667
#define DEFAULT_CHANNEL	"#zephyrbot"

static struct net_app_ctx app_ctx;

#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL)
NET_PKT_TX_SLAB_DEFINE(tx_tcp, 15);
NET_PKT_DATA_POOL_DEFINE(data_tcp, 30);

static struct k_mem_slab *tx_slab(void)
{
	return &tx_tcp;
}

static struct net_buf_pool *data_pool(void)
{
	return &data_tcp;
}
#else
#define tx_slab NULL
#define data_pool NULL
#endif /* CONFIG_NET_CONTEXT_NET_PKT_POOL */

static void
panic(const char *msg)
{
	SYS_LOG_ERR("Panic: %s", msg);
	for (;;) {
		k_sleep(K_FOREVER);
	}
}

static int
transmit(char buffer[], size_t len)
{
	struct net_pkt *send_pkt;
	int ret;

	send_pkt = net_app_get_net_pkt(&app_ctx, AF_UNSPEC, BUF_ALLOC_TIMEOUT);
	if (!send_pkt) {
		SYS_LOG_ERR("Unable to get TX packet, not enough memory.");
		return -ENOMEM;
	}

	if (!net_pkt_append_all(send_pkt, len, (u8_t *)buffer,
				BUF_ALLOC_TIMEOUT)) {
		net_pkt_unref(send_pkt);
		return -EINVAL;
	}

	ret = net_app_send_pkt(&app_ctx, send_pkt,
			       &app_ctx.default_ctx->remote,
			       NET_SOCKADDR_MAX_SIZE, K_NO_WAIT, NULL);
	if (ret < 0) {
		net_pkt_unref(send_pkt);
	}

	return ret;
}

static void
on_cmd_ping(char *umask, char *cmd, size_t len)
{
	char pong[32];
	int ret;

	SYS_LOG_INF("Got PING command from server: %s", cmd);

	ret = snprintk(pong, 32, "PONG :%s", cmd + 1);
	if (ret < sizeof(pong)) {
		ret = transmit(pong, ret);
		if (ret < 0) {
			SYS_LOG_INF("Transmit error: %d", ret);
		}
	}
}

static void
on_cmd_privmsg(char *umask, char *cmd, size_t len)
{
	char *space;

	if (!umask) {
		/* Don't know how this got here, so ignore */
		return;
	}

	SYS_LOG_DBG("Got message from umask %s: %s", umask, cmd);

	space = memchr(cmd, ' ', len);
	if (!space) {
		return;
	}

	*space = '\0';

	if (*(space + 1) != ':') {
		/* Just ignore messages without a ':' after the space */
		SYS_LOG_DBG("Ignoring message umask: %s: %s", umask, space);
		return;
	}

	space += 2; /* Jump over the ':', pointing to the message itself */

	/* check for a private message from another user */
	if (!strncmp(nick_buf, cmd, NICK_BUFFER_SIZE)) {
		on_msg_rcvd(umask, umask, space);
	} else {
		on_msg_rcvd(cmd, umask, space);
	}
}

#define CMD(cmd_, cb_) { \
	.cmd = cmd_ " ", \
	.cmd_len = sizeof(cmd_ " ") - 1, \
	.func = on_cmd_ ## cb_ \
}
static void
process_command(char *cmd, size_t len)
{
	static const struct {
		const char *cmd;
		size_t cmd_len;
		void (*func)(char *umask, char *cmd, size_t len);
	} commands[] = {
		CMD("PING", ping),
		CMD("PRIVMSG", privmsg),
	};
	char *umask;
	int i;

	if (*cmd == ':') {
		char *space = memchr(cmd, ' ', len);

		if (!space) {
			return;
		}

		umask = cmd + 1;
		*space = '\0';

		len -= (space - cmd) + 1;
		if (!len) {
			return;
		}

		cmd = space + 1;

		SYS_LOG_DBG("Received from server, umask=%s: %s", umask, cmd);
	} else {
		umask = NULL;

		SYS_LOG_DBG("Received from server (no umask): %s", cmd);
	}

	for (i = 0; i < ARRAY_SIZE(commands); i++) {
		if (len < commands[i].cmd_len) {
			continue;
		}
		if (!strncmp(cmd, commands[i].cmd, commands[i].cmd_len)) {
			SYS_LOG_DBG("Command has handler, executing");

			cmd += commands[i].cmd_len;
			len -= commands[i].cmd_len;
			commands[i].func(umask, cmd, len);

			return;
		}
	}

	/* TODO: handle notices, CTCP, etc */
	SYS_LOG_DBG("Could not find handler to handle %s, ignoring", cmd);
}
#undef CMD

static void
on_context_recv(struct net_app_ctx *ctx, struct net_pkt *pkt,
		int status, void *data)
{
	struct net_buf *tmp;
	u16_t pos = 0;

	if (!pkt) {
		/* TODO: notify of disconnection, maybe reconnect? */
		SYS_LOG_ERR("Disconnected\n");
		return;
	}

	if (status) {
		/* TODO: handle connection error */
		SYS_LOG_ERR("Connection error: %d\n", -status);
		net_pkt_unref(pkt);
		return;
	}

	/* tmp points to fragment containing IP header */
	tmp = pkt->frags;
	/* skip pos to the first TCP payload */
	pos = net_pkt_appdata(pkt) - tmp->data;

	while (true) {
		if (cmd_len >= CMD_BUFFER_SIZE) {
			SYS_LOG_WRN("cmd_buf overrun (>%d) Ignoring",
				    CMD_BUFFER_SIZE);
			cmd_len = 0;
		}

		tmp = net_frag_read(tmp, pos, &pos, 1, cmd_buf + cmd_len);
		if (*(cmd_buf + cmd_len) == '\r') {
			cmd_buf[cmd_len] = '\0';
			process_command((char *)cmd_buf, cmd_len);
			/* skip the \n after \r */
			tmp = net_frag_read(tmp, pos, &pos, 1, NULL);
			cmd_len = 0;
		} else {
			cmd_len++;
		}

		if (!tmp || pos == 0xFFFF) {
			break;
		}
	}

	net_pkt_unref(pkt);
}

static int
zirc_nick_set(const char *nick)
{
	char buffer[32];
	int ret;

	SYS_LOG_INF("Setting nickname to: %s", nick);

	ret = snprintk(buffer, sizeof(buffer), "NICK %s\r\n", nick);
	if (ret < 0 || ret >= sizeof(buffer)) {
		return -EINVAL;
	}

	return transmit(buffer, ret);
}

static int
zirc_user_set(const char *user, const char *realname)
{
	char buffer[64];
	int ret;

	SYS_LOG_INF("Setting user to: %s, real name to: %s", user, realname);

	ret = snprintk(buffer, sizeof(buffer), "USER %s * * :%s\r\n",
		       user, realname);
	if (ret < 0 || ret >= sizeof(buffer)) {
		return -EINVAL;
	}

	return transmit(buffer, ret);
}

static int
zirc_chan_join(const char *channel)
{
	char buffer[32];
	int ret;

	SYS_LOG_INF("Joining channel: %s", channel);

	ret = snprintk(buffer, sizeof(buffer), "JOIN %s\r\n", channel);
	if (ret < 0 || ret >= sizeof(buffer)) {
		return -EINVAL;
	}

	ret = transmit(buffer, ret);
	return ret;
}

static int
zirc_chan_part(char *chan_name)
{
	char buffer[32];
	int ret;

	SYS_LOG_INF("Leaving channel: %s", chan_name);

	ret = snprintk(buffer, sizeof(buffer), "PART %s\r\n", chan_name);
	if (ret < 0 || ret >= sizeof(buffer)) {
		return -EINVAL;
	}

	ret = transmit(buffer, ret);
	if (ret < 0) {
		return ret;
	}

	return 0;
}

static int
zirc_connect(const char *host, int port)
{
	int ret;

	SYS_LOG_INF("Connecting to %s:%d...", host, port);

	ret = net_app_init_tcp_client(&app_ctx, NULL, NULL,
				      host, port,
				      WAIT_TIMEOUT, NULL);
	if (ret < 0) {
		SYS_LOG_ERR("net_app_init_tcp_client err:%d", ret);
		return ret;
	}

#if defined(CONFIG_NET_CONTEXT_NET_PKT_POOL)
	net_app_set_net_pkt_pool(&app_ctx, tx_slab, data_pool);
#endif

	/* set net_app callbacks */
	ret = net_app_set_cb(&app_ctx, NULL, on_context_recv, NULL, NULL);
	if (ret < 0) {
		SYS_LOG_ERR("Could not set receive callback (err:%d)", ret);
		return ret;
	}

	ret = net_app_connect(&app_ctx, CONNECT_TIMEOUT);
	if (ret < 0) {
		SYS_LOG_ERR("Cannot connect (%d)", ret);
		panic("Can't init network");
	}

	if (zirc_nick_set(nick_buf) < 0) {
		panic("Could not set nick");
	}

	if (zirc_user_set(nick_buf, "Zephyr IRC Bot") < 0) {
		panic("Could not set user");
	}

	if (zirc_chan_join(DEFAULT_CHANNEL) < 0) {
		panic("Could not join channel");
	}
	return ret;
}

static int
zirc_disconnect(void)
{
	SYS_LOG_INF("Disconnecting");
	cmd_len = 0;
	net_app_close(&app_ctx);
	return net_app_release(&app_ctx);
}

static int
zirc_chan_send_msg(const char *chan_name, const char *msg)
{
	char buffer[128];

	SYS_LOG_INF("Sending to channel/user %s: %s", chan_name, msg);

	while (*msg) {
		int msglen, txret;

		msglen = snprintk(buffer, sizeof(buffer), "PRIVMSG %s :%s\r\n",
				  chan_name, msg);

		if (msglen < 0) {
			return msglen;
		}

		txret = transmit(buffer, msglen);
		if (txret < 0) {
			return txret;
		}

		if (msglen < sizeof(buffer)) {
			return 0;
		}

		msg += msglen - sizeof("PRIVMSG  :\r\n") - 1 +
		       strlen(chan_name);
	}

	return 0;
}

static void
on_cmd_hello(char *chan_name, const char *nick, const char *msg)
{
	char buf[64];
	int ret;

	ret = snprintk(buf, sizeof(buf), "Hello, %s!", nick);
	if (ret < 0 || ret >= sizeof(buf)) {
		zirc_chan_send_msg(chan_name, "Hello, world!  (Your nick is "
				   "larger than my stack allows.)");
	} else {
		zirc_chan_send_msg(chan_name, buf);
	}
}

static void
on_cmd_random(char *chan_name, const char *nick, const char *msg)
{
	char buf[128];
	s32_t num = sys_rand32_get();
	int ret;

	switch (num & 3) {
	case 0:
		ret = snprintk(buf, sizeof(buf), "Here's a fresh, random "
			       "32-bit integer, %s: %d", nick, num);
		break;
	case 1:
		ret = snprintk(buf, sizeof(buf), "Another number, fresh off "
			       "the PRNG: %d", num);
		break;
	case 2:
		ret = snprintk(buf, sizeof(buf), "Some calculations "
			       "with senseless constants yielded %d", num);
		break;
	case 3:
		ret = snprintk(buf, sizeof(buf), "I rolled a fair dice and "
			       "the result is...  %d", num);
		break;
	default:
		/* Shut up the compiler, as this condition is impossible.  */
		ret = -1;
	}

	if (ret < 0 || ret >= sizeof(buf)) {
		zirc_chan_send_msg(chan_name, "I rolled a fair dice and the "
				   "number is...  7.3");
	} else {
		zirc_chan_send_msg(chan_name, buf);
	}
}

static bool
read_led(void)
{
	u32_t led = 0;
	int r;

	if (!led0) {
		return fake_led;
	}

	r = gpio_pin_read(led0, LED_PIN, &led);
	if (r < 0) {
		return false;
	}

	return !led;
}

static void
write_led(bool led)
{
	if (!led0) {
		fake_led = led;
	} else {
		gpio_pin_write(led0, LED_PIN, !led);
	}
}

static void
on_cmd_led_off(char *chan_name, const char *nick, const char *msg)
{
	zirc_chan_send_msg(chan_name, "The LED should be *off* now");
	write_led(false);
}

static void
on_cmd_led_on(char *chan_name, const char *nick, const char *msg)
{
	zirc_chan_send_msg(chan_name, "The LED should be *on* now");
	write_led(true);
}

static void
on_cmd_led_toggle(char *chan_name, const char *nick, const char *msg)
{
	if (read_led()) {
		on_cmd_led_off(chan_name, nick, msg);
	} else {
		on_cmd_led_on(chan_name, nick, msg);
	}
}

static void
on_cmd_rejoin(char *chan_name, const char *nick, const char *msg)
{
	/* make sure this isn't a private message */
	if (!strncmp(nick, chan_name, NICK_BUFFER_SIZE)) {
		zirc_chan_send_msg(chan_name,
				   "I can't rejoin a private message!");
	} else {
		zirc_chan_part(chan_name);
		zirc_chan_join(chan_name);
	}
}

static void
on_cmd_disconnect(char *chan_name, const char *nick, const char *msg)
{
	zirc_disconnect();
}

#define CMD(c) { \
	.cmd = "!" #c, \
	.cmd_len = sizeof(#c) - 1, \
	.func = on_cmd_ ## c \
}
static void
on_msg_rcvd(char *chan_name, char *umask, char *msg)
{
	static const struct {
		const char *cmd;
		size_t cmd_len;
		void (*func)(char *chan_name, const char *nick,
			     const char *msg);
	} commands[] = {
		CMD(hello),
		CMD(random),
		CMD(led_toggle),
		CMD(led_off),
		CMD(led_on),
		CMD(rejoin),
		CMD(disconnect),
	};
	char *nick, *end;
	int i;

	if (!umask) {
		return;
	}

	SYS_LOG_DBG("Received from umask %s: %s", umask, msg);

	end = strchr(umask, '!');
	if (!end) {
		nick = NULL;
	} else {
		*end = '\0';
		nick = umask;
	}

	for (i = 0; i < ARRAY_SIZE(commands); i++) {
		if (!strncmp(msg, commands[i].cmd, commands[i].cmd_len)) {
			msg += commands[i].cmd_len;
			commands[i].func(chan_name, nick, msg);
			return;
		}
	}

	if (!strncmp(msg, "!help", 5)) {
		char msg[64];
		int ret;

		/* TODO: loop through commands[] and create help text */
		/* TODO: add help message to command, "!help command"
		 *       sends it back
		 */

		ret = snprintk(msg, sizeof(msg), "%s, you're a grown up, figure"
			       " it out", nick);
		if (ret < 0 || ret >= sizeof(msg)) {
			zirc_chan_send_msg(chan_name,
					   "Your nick is too long, and my"
					   " stack is limited. Can't help you");
		} else {
			zirc_chan_send_msg(chan_name, msg);
		}
	}
}
#undef CMD

void main(void)
{
	int ret;

	SYS_LOG_INF(APP_BANNER);

	led0 = device_get_binding(LED_GPIO_NAME);
	if (led0) {
		gpio_pin_configure(led0, LED_PIN, GPIO_DIR_OUT);
	}

	cmd_len = 0;

	/* setup IRC nick for max 16 chars */
	ret = snprintk(nick_buf, sizeof(nick_buf), "zephyrbot%05u",
		       sys_rand32_get() & 0xFFFF);
	if (ret < 0 || ret >= sizeof(nick_buf)) {
		panic("Can't fill nick buffer");
	}

	ret = zirc_connect(DEFAULT_SERVER, DEFAULT_PORT);
	if (ret < 0 && ret != -EINPROGRESS) {
		panic("Could not connect");
	}

	for (;;) {
		k_sleep(K_FOREVER);
	}
}
