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

#if 1
#define SYS_LOG_DOMAIN "irc"
#define NET_LOG_ENABLED 1
#endif

#include <board.h>
#include <drivers/rand32.h>
#include <errno.h>
#include <gpio.h>
#include <net/net_pkt.h>
#include <net/net_context.h>
#include <net/net_core.h>
#include <net/net_if.h>
#include <stdio.h>
#include <zephyr.h>
#include <net/dns_resolve.h>
#include <net/net_mgmt.h>
#include <net/net_event.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 CMD_BUFFER_SIZE 256
static u8_t cmd_buf[CMD_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 */

#if defined(CONFIG_NET_IPV6)

#define ZIRC_AF_INET		AF_INET6
#define ZIRC_SOCKADDR_IN	sockaddr_in6

#if defined(CONFIG_NET_APP_MY_IPV6_ADDR)
#define ZIRC_LOCAL_IP_ADDR	CONFIG_NET_APP_MY_IPV6_ADDR
#else
#define ZIRC_LOCAL_IP_ADDR	"2001:db8::1"
#endif /* CONFIG_NET_APP_MY_IPV6_ADDR */

#if defined(CONFIG_NET_APP_PEER_IPV6_ADDR)
#define ZIRC_PEER_IP_ADDR	CONFIG_NET_APP_PEER_IPV6_ADDR
#else
#define ZIRC_PEER_IP_ADDR	"2001:db8::2"
#endif /* CONFIG_NET_APP_PEER_IPV6_ADDR */

#else /* CONFIG_NET_IPV4 */

#define ZIRC_AF_INET		AF_INET
#define ZIRC_SOCKADDR_IN	sockaddr_in

#if defined(CONFIG_NET_APP_MY_IPV4_ADDR)
#define ZIRC_LOCAL_IP_ADDR	CONFIG_NET_APP_MY_IPV4_ADDR
#else
#define ZIRC_LOCAL_IP_ADDR	"192.0.2.1"
#endif /* CONFIG_NET_APP_MY_IPV4_ADDR */

#if defined(CONFIG_NET_APP_PEER_IPV4_ADDR)
#define ZIRC_PEER_IP_ADDR	CONFIG_NET_APP_PEER_IPV4_ADDR
#else
#define ZIRC_PEER_IP_ADDR	"192.0.2.2"
#endif /* CONFIG_NET_APP_PEER_IPV4_ADDR */

#endif

/* DNS API */
#define DNS_QUERY_TIMEOUT K_SECONDS(4)

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

struct zirc_chan;

typedef void (*on_privmsg_rcvd_cb_t)(void *data, struct zirc_chan *chan,
				  char *umask, char *msg);

struct zirc {
	struct sockaddr local_addr;
	struct sockaddr remote_addr;

#if defined(CONFIG_DNS_RESOLVER)
	struct k_sem wait_dns;
#endif

	struct k_sem wait_iface;

	struct net_context *conn;
	struct zirc_chan *chans;

	void *data;
};

struct zirc_chan {
	struct zirc *irc;
	struct zirc_chan *next;

	const char *chan;

	on_privmsg_rcvd_cb_t on_privmsg_rcvd;
	void *data;
};

static void on_msg_rcvd(void *data, struct zirc_chan *chan, char *umask,
			char *msg);

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

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

	send_pkt = net_pkt_get_tx(ctx, K_FOREVER);
	if (!send_pkt) {
		return -ENOMEM;
	}

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

	return net_context_send(send_pkt, NULL, K_NO_WAIT, NULL, NULL);
}

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

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

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

static void
on_cmd_privmsg(struct zirc *irc, char *umask, char *cmd, size_t len)
{
	struct zirc_chan *chan;
	char *space;

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

	NET_INFO("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 */
		return;
	}

	space += 2; /* Jump over the ':', pointing to the message itself */
	for (chan = irc->chans; chan; chan = chan->next) {
		if (!strncmp(chan->chan, cmd, space - cmd)) {
			chan->on_privmsg_rcvd(chan->data, chan, umask, space);
			return;
		}
	}

	/* TODO: could be a private message (from another user) */
	NET_INFO("Unknown privmsg received: %.*s\n", (int)len, cmd);
}

#define CMD(cmd_, cb_) { \
	.cmd = cmd_ " ", \
	.cmd_len = sizeof(cmd_ " ") - 1, \
	.func = on_cmd_ ## cb_ \
}
static void
process_command(struct zirc *irc, char *cmd, size_t len)
{
	static const struct {
		const char *cmd;
		size_t cmd_len;
		void (*func)(struct zirc *zirc, 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;

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

		NET_INFO("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)) {
			NET_INFO("Command has handler, executing");

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

			return;
		}
	}

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

static void
on_context_recv(struct net_context *ctx, struct net_pkt *pkt,
				int status, void *data)
{
	struct zirc *irc = data;
	struct net_buf *tmp;
	u8_t *end_of_line;
	size_t len;
	u16_t pos = 0, cmd_len = 0;

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

	if (status) {
		/* TODO: handle connection error */
		NET_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 (tmp) {
		len = tmp->len - pos;

		end_of_line = memchr(tmp->data + pos, '\r', len);
		if (end_of_line) {
			len = end_of_line - (tmp->data + pos);
		}

		if (cmd_len + len > sizeof(cmd_buf)) {
			/* overrun cmd_buf - bail out */
			NET_ERR("CMD BUFFER OVERRUN!! %zu > %zu",
				cmd_len + len,
				sizeof(cmd_buf));
			break;
		}

		tmp = net_frag_read(tmp, pos, &pos, len, cmd_buf + cmd_len);
		cmd_len += len;

		if (end_of_line) {
			/* skip the /n char after /r */
			if (tmp) {
				tmp = net_frag_read(tmp, pos, &pos, 1, NULL);
			}

			cmd_buf[cmd_len] = '\0';
			process_command(irc, (char *)cmd_buf, cmd_len);
			cmd_len = 0;
		}
	}

	net_pkt_unref(pkt);

	/* TODO: handle messages that spans multiple packets? */
}

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

	NET_INFO("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(irc->conn, buffer, ret);
}

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

	NET_INFO("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(irc->conn, buffer, ret);
}

static int
zirc_chan_join(struct zirc *irc, struct zirc_chan *chan,
	       const char *channel,
	       on_privmsg_rcvd_cb_t on_privmsg_rcvd,
	       void *data)
{
	char buffer[32];
	int ret;

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

	if (!on_privmsg_rcvd) {
		return -EINVAL;
	}

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

	ret = transmit(irc->conn, buffer, ret);
	if (ret < 0) {
		return ret;
	}

	chan->irc = irc;
	chan->chan = channel;
	chan->on_privmsg_rcvd = on_privmsg_rcvd;
	chan->data = data;

	chan->next = irc->chans;
	irc->chans = chan;

	return 0;
}

static int
zirc_chan_part(struct zirc_chan *chan)
{
	struct zirc_chan **cc, *c;
	char buffer[32];
	int ret;

	NET_INFO("Leaving channel: %s", chan->chan);

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

	ret = transmit(chan->irc->conn, buffer, ret);
	if (ret < 0) {
		return ret;
	}

	for (cc = &chan->irc->chans, c = chan->irc->chans;
	     c; cc = &c->next, c = c->next) {
		if (c == chan) {
			*cc = c->next;
			return 0;
		}
	}

	return -ENOENT;
}

#if defined(CONFIG_NET_IPV6)
static int in_addr_set(sa_family_t family,
		       const char *ip_addr,
		       int port,
		       struct sockaddr *_sockaddr)
{
	int rc = 0;

	_sockaddr->family = family;

	if (ip_addr) {
		if (family == AF_INET6) {
			rc = net_addr_pton(family,
					   ip_addr,
					   &net_sin6(_sockaddr)->sin6_addr);
		} else {
			rc = net_addr_pton(family,
					   ip_addr,
					   &net_sin(_sockaddr)->sin_addr);
		}

		if (rc < 0) {
			NET_ERR("Invalid IP address: %s", ip_addr);
			return -EINVAL;
		}
	}

	if (port >= 0) {
		if (family == AF_INET6) {
			net_sin6(_sockaddr)->sin6_port = htons(port);
		} else {
			net_sin(_sockaddr)->sin_port = htons(port);
		}
	}

	return rc;
}
#endif

#if defined(CONFIG_DNS_RESOLVER)
static void resolve_cb(enum dns_resolve_status status,
			struct dns_addrinfo *info,
			void *user_data)
{
	struct zirc *irc = user_data;

	/* Note that we cannot do any connection establishment in the DNS
	 * callback as the DNS query will timeout very soon. We inform the
	 * connect function via semaphore when it can continue.
	 */
	k_sem_give(&irc->wait_dns);

	if (status != DNS_EAI_INPROGRESS || !info) {
		return;
	}

#if defined(CONFIG_NET_IPV6)
	if (info->ai_family == AF_INET6) {
		net_ipaddr_copy(&net_sin6(&irc->remote_addr)->sin6_addr,
				&net_sin6(&info->ai_addr)->sin6_addr);
		net_sin6(&irc->remote_addr)->sin6_port = htons(DEFAULT_PORT);
		net_sin6(&irc->remote_addr)->sin6_family = AF_INET6;
		irc->remote_addr.family = AF_INET6;
	} else
#endif
#if defined(CONFIG_NET_IPV4)
	if (info->ai_family == AF_INET) {
		net_ipaddr_copy(&net_sin(&irc->remote_addr)->sin_addr,
				&net_sin(&info->ai_addr)->sin_addr);
		net_sin(&irc->remote_addr)->sin_port = htons(DEFAULT_PORT);
		net_sin(&irc->remote_addr)->sin_family = AF_INET;
		irc->remote_addr.family = AF_INET;
	} else
#endif
	{
		NET_ERR("Invalid IP address family %d", info->ai_family);
		return;
	}

	return;
}

static inline int zirc_dns_lookup(const char *host, void *user_data)
{
	return dns_get_addr_info(host,
#ifdef CONFIG_NET_IPV6
				 DNS_QUERY_TYPE_AAAA,
#else
				 DNS_QUERY_TYPE_A,
#endif
				 NULL,
				 resolve_cb,
				 user_data,
				 DNS_QUERY_TIMEOUT);
}
#endif /* CONFIG_DNS_RESOLVER */

static int
zirc_connect(struct zirc *irc, const char *host, int port, void *data)
{
	struct net_if *iface;
	struct zirc_chan *chan;
	int ret;
	char name_buf[32];

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

	ret = net_context_get(ZIRC_AF_INET, SOCK_STREAM, IPPROTO_TCP,
			      &irc->conn);
	if (ret < 0) {
		NET_DBG("Could not get new context: %d", ret);
		return ret;
	}

	iface = net_if_get_default();
	if (!iface) {
		NET_DBG("Could not get new context: %d", ret);
		return -EIO;
	}

#if defined(CONFIG_DNS_RESOLVER)
	irc->data = data;

	ret = zirc_dns_lookup(host, irc);
	if (ret < 0) {
		NET_ERR("Could not peform DNS lookup on host %s: %d",
			host, ret);
		goto connect_exit;
	}

	/* We continue the connection after the server name has been resolved.
	 */
	k_sem_take(&irc->wait_dns, K_FOREVER);
#else
	ret = in_addr_set(ZIRC_AF_INET, ZIRC_PEER_IP_ADDR,
			  port, &irc->remote_addr);
	if (ret < 0) {
		goto connect_exit;
	}
#endif

	ret = net_context_bind(irc->conn, &irc->local_addr,
			       sizeof(struct ZIRC_SOCKADDR_IN));
	if (ret < 0) {
		NET_DBG("Could not bind to local address: %d", ret);
		goto connect_exit;
	}

	irc->data = data;

	ret = net_context_connect(irc->conn, &irc->remote_addr,
				  sizeof(struct ZIRC_SOCKADDR_IN),
				  NULL, K_FOREVER, irc);
	if (ret < 0) {
		NET_DBG("Could not connect, errno %d", ret);
		goto connect_exit;
	}

	net_context_recv(irc->conn, on_context_recv, K_NO_WAIT, irc);

	chan = irc->data;

	ret = snprintk(name_buf, sizeof(name_buf), "zephyrbot%u",
		       sys_rand32_get());
	if (ret < 0 || ret >= sizeof(name_buf)) {
		panic("Can't fill name buffer");
	}

	if (zirc_nick_set(irc, name_buf) < 0) {
		panic("Could not set nick");
	}

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

	if (zirc_chan_join(irc, chan, DEFAULT_CHANNEL, on_msg_rcvd, NULL) < 0) {
		panic("Could not join channel");
	}
	return ret;

connect_exit:
	net_context_put(irc->conn);
	return ret;
}

static int
zirc_disconnect(struct zirc *irc)
{
	NET_INFO("Disconnecting");

	irc->chans = NULL;
	return net_context_put(irc->conn);
}

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

	NET_INFO("Sending to channel %s: %s", chan->chan, msg);

	while (*msg) {
		int msglen, txret;

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

		if (msglen < 0) {
			return msglen;
		}

		txret = transmit(chan->irc->conn, buffer, msglen);
		if (txret < 0) {
			return txret;
		}

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

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

	return 0;
}

static void
on_cmd_hello(struct zirc_chan *chan, 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, "Hello, world!  (Your nick is "
				   "larger than my stack allows.)");
	} else {
		zirc_chan_send_msg(chan, buf);
	}
}

static void
on_cmd_random(struct zirc_chan *chan, 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, "I rolled a fair dice and the "
				   "number is...  7.3");
	} else {
		zirc_chan_send_msg(chan, 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(struct zirc_chan *chan, const char *nick, const char *msg)
{
	zirc_chan_send_msg(chan, "The LED should be *off* now");
	write_led(false);
}

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

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

static void
on_cmd_rejoin(struct zirc_chan *chan, const char *nick, const char *msg)
{
	zirc_chan_part(chan);
	zirc_chan_join(chan->irc, chan, DEFAULT_CHANNEL, on_msg_rcvd, NULL);
}

static void
on_cmd_disconnect(struct zirc_chan *chan, const char *nick, const char *msg)
{
	zirc_disconnect(chan->irc);
}

#define CMD(c) { \
	.cmd = "!" #c, \
	.cmd_len = sizeof(#c) - 1, \
	.func = on_cmd_ ## c \
}
static void
on_msg_rcvd(void *data, struct zirc_chan *chan, char *umask, char *msg)
{
	static const struct {
		const char *cmd;
		size_t cmd_len;
		void (*func)(struct zirc_chan *chan, 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;
	}

	NET_INFO("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, nick, msg);
			return;
		}
	}

	if (!strncmp(msg, "!help", 5)) {
		char msg[32];
		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, "Your nick is too long, and my"
					   " stack is limited. Can't help you");
		} else {
			zirc_chan_send_msg(chan, msg);
		}
	}
}
#undef CMD

#if defined(CONFIG_NET_DHCPV4) && !defined(CONFIG_NET_IPV6)
#define DHCPV4_TIMEOUT K_SECONDS(30)

static struct net_mgmt_event_callback mgmt4_cb;
static K_SEM_DEFINE(dhcpv4_ok, 0, UINT_MAX);

static void ipv4_addr_add_handler(struct net_mgmt_event_callback *cb,
				  u32_t mgmt_event,
				  struct net_if *iface)
{
	int i;

	if (mgmt_event != NET_EVENT_IPV4_ADDR_ADD) {
		return;
	}

	for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) {
		struct net_if_addr *if_addr = &iface->ipv4.unicast[i];

		if (if_addr->addr_type != NET_ADDR_DHCP || !if_addr->is_used) {
			continue;
		}

#if CONFIG_SYS_LOG_NET_LEVEL > 2
		{
			char hr_addr[NET_IPV4_ADDR_LEN];

			NET_INFO("IPv4 address: %s",
				 net_addr_ntop(AF_INET,
					       &if_addr->address.in_addr,
					       hr_addr, NET_IPV4_ADDR_LEN));
			NET_INFO("Lease time: %u seconds",
				 iface->dhcpv4.lease_time);
			NET_INFO("Subnet: %s",
				 net_addr_ntop(AF_INET, &iface->ipv4.netmask,
					       hr_addr, NET_IPV4_ADDR_LEN));
			NET_INFO("Router: %s",
				 net_addr_ntop(AF_INET, &iface->ipv4.gw,
					       hr_addr, NET_IPV4_ADDR_LEN));
		}
#endif
		break;
	}

	k_sem_give(&dhcpv4_ok);
}

static void setup_dhcpv4(struct zirc *irc, struct net_if *iface)
{
	NET_INFO("Running dhcpv4 client...");

	net_mgmt_init_event_callback(&mgmt4_cb, ipv4_addr_add_handler,
				     NET_EVENT_IPV4_ADDR_ADD);
	net_mgmt_add_event_callback(&mgmt4_cb);

	net_dhcpv4_start(iface);

	if (k_sem_take(&dhcpv4_ok, DHCPV4_TIMEOUT) < 0) {
		panic("No IPv4 address.");
	}

	net_ipaddr_copy(&net_sin(&irc->local_addr)->sin_addr,
			&iface->dhcpv4.requested_ip);
	irc->local_addr.family = AF_INET;
	net_sin(&irc->local_addr)->sin_family = AF_INET;
	net_sin(&irc->local_addr)->sin_port = 0;

	k_sem_give(&irc->wait_iface);
}
#else
#define setup_dhcpv4(...)
#endif /* CONFIG_NET_DHCPV4 */

#if defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_DHCPV4)

static void setup_ipv4(struct zirc *irc, struct net_if *iface)
{
#if CONFIG_SYS_LOG_NET_LEVEL > 2
	char hr_addr[NET_IPV4_ADDR_LEN];
#endif
	struct in_addr addr;

	if (net_addr_pton(AF_INET, ZIRC_LOCAL_IP_ADDR, &addr)) {
		NET_ERR("Invalid address: %s", ZIRC_LOCAL_IP_ADDR);
		return;
	}

	net_if_ipv4_addr_add(iface, &addr, NET_ADDR_MANUAL, 0);

	NET_INFO("IPv4 address: %s",
		 net_addr_ntop(AF_INET, &addr, hr_addr, NET_IPV4_ADDR_LEN));

	if (in_addr_set(ZIRC_AF_INET, ZIRC_LOCAL_IP_ADDR, 0,
			&irc->local_addr) < 0) {
		NET_ERR("Invalid IP address: %s", ZIRC_LOCAL_IP_ADDR);
	}

	k_sem_give(&irc->wait_iface);
}

#else
#define setup_ipv4(...)
#endif /* CONFIG_NET_IPV4 && !CONFIG_NET_DHCPV4 */

#if defined(CONFIG_NET_IPV6)

#define DAD_TIMEOUT K_SECONDS(3)

static struct net_mgmt_event_callback mgmt6_cb;
static K_SEM_DEFINE(dad_ok, 0, UINT_MAX);
static struct in6_addr laddr;

static void ipv6_dad_ok_handler(struct net_mgmt_event_callback *cb,
				u32_t mgmt_event,
				struct net_if *iface)
{
	struct net_if_addr *ifaddr;

	if (mgmt_event != NET_EVENT_IPV6_DAD_SUCCEED) {
		return;
	}

	ifaddr = net_if_ipv6_addr_lookup(&laddr, &iface);
	if (!ifaddr ||
	    !(net_ipv6_addr_cmp(&ifaddr->address.in6_addr, &laddr) &&
	      ifaddr->addr_state == NET_ADDR_PREFERRED)) {
		/* Address is not yet properly setup */
		return;
	}

	k_sem_give(&dad_ok);
}

static void setup_ipv6(struct zirc *irc, struct net_if *iface)
{
#if CONFIG_SYS_LOG_NET_LEVEL > 2
	char hr_addr[NET_IPV6_ADDR_LEN];
#endif

	if (net_addr_pton(AF_INET6, ZIRC_LOCAL_IP_ADDR, &laddr)) {
		NET_ERR("Invalid address: %s", ZIRC_LOCAL_IP_ADDR);
		return;
	}

	NET_INFO("IPv6 address: %s",
		 net_addr_ntop(AF_INET6, &laddr, hr_addr, NET_IPV6_ADDR_LEN));

	net_mgmt_init_event_callback(&mgmt6_cb, ipv6_dad_ok_handler,
				     NET_EVENT_IPV6_DAD_SUCCEED);
	net_mgmt_add_event_callback(&mgmt6_cb);

	net_if_ipv6_addr_add(iface, &laddr, NET_ADDR_MANUAL, 0);

	if (k_sem_take(&dad_ok, DAD_TIMEOUT) < 0) {
		panic("IPv6 address setup failed.");
	}

	if (in_addr_set(ZIRC_AF_INET, ZIRC_LOCAL_IP_ADDR, 0,
			&irc->local_addr) < 0) {
		NET_ERR("Invalid IP address: %s", ZIRC_LOCAL_IP_ADDR);
	}

	k_sem_give(&irc->wait_iface);
}

#else
#define setup_ipv6(...)
#endif /* CONFIG_NET_IPV6 */

static void
initialize_network(struct zirc *irc)
{
	struct net_if *iface;

	NET_INFO("Initializing network");

#if defined(CONFIG_DNS_RESOLVER)
	k_sem_init(&irc->wait_dns, 0, UINT_MAX);
#endif

	k_sem_init(&irc->wait_iface, 0, UINT_MAX);

	iface = net_if_get_default();
	if (!iface) {
		panic("No default network interface");
	}

#if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_DHCPV6)
	/* TODO: IPV6 DHCP */
#elif !defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_DHCPV4)
	setup_dhcpv4(irc, iface);
#elif !defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_IPV4)
	setup_ipv4(irc, iface);
#else
	setup_ipv6(irc, iface);
#endif

	/* Wait until we are ready to continue */
	k_sem_take(&irc->wait_iface, K_FOREVER);
}

static void
initialize_hardware(void)
{
	NET_INFO("Initializing hardware");

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

void main(void)
{
	struct zirc irc = { };
	struct zirc_chan chan = { };
	int ret;

	NET_INFO("Zephyr IRC bot sample");

	initialize_network(&irc);
	initialize_hardware();

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

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