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

#include <logging/log.h>
LOG_MODULE_REGISTER(net_nats_sample, LOG_LEVEL_DBG);

#include <gpio.h>
#include <net/net_context.h>
#include <net/net_core.h>
#include <net/net_if.h>
#include <zephyr.h>

#include "nats.h"

/* LED */
#ifndef LED0_GPIO_CONTROLLER
#ifdef LED0_GPIO_PORT
#define LED0_GPIO_CONTROLLER 	LED0_GPIO_PORT
#else
#define LED0_GPIO_CONTROLLER "(fail)"
#define LED0_GPIO_PIN 0
#endif
#endif

#define LED_GPIO_NAME LED0_GPIO_CONTROLLER
#define LED_PIN LED0_GPIO_PIN

static struct device *led0;
static bool fake_led;

/* Network Config */

#if defined(CONFIG_NET_IPV6)

#define NATS_AF_INET		AF_INET6
#define NATS_SOCKADDR_IN	sockaddr_in6

#if defined(CONFIG_NET_CONFIG_MY_IPV6_ADDR)
#define NATS_LOCAL_IP_ADDR	CONFIG_NET_CONFIG_MY_IPV6_ADDR
#else
#define NATS_LOCAL_IP_ADDR	"2001:db8::1"
#endif /* CONFIG_NET_CONFIG_MY_IPV6_ADDR */

#if defined(CONFIG_NET_CONFIG_PEER_IPV6_ADDR)
#define NATS_PEER_IP_ADDR	CONFIG_NET_CONFIG_PEER_IPV6_ADDR
#else
#define NATS_PEER_IP_ADDR	"2001:db8::2"
#endif /* CONFIG_NET_CONFIG_PEER_IPV6_ADDR */

#else /* CONFIG_NET_IPV4 */

#define NATS_AF_INET		AF_INET
#define NATS_SOCKADDR_IN	sockaddr_in

#if defined(CONFIG_NET_CONFIG_MY_IPV4_ADDR)
#define NATS_LOCAL_IP_ADDR	CONFIG_NET_CONFIG_MY_IPV4_ADDR
#else
#define NATS_LOCAL_IP_ADDR	"192.168.0.1"
#endif /* CONFIG_NET_CONFIG_MY_IPV4_ADDR */

#if defined(CONFIG_NET_CONFIG_PEER_IPV4_ADDR)
#define NATS_PEER_IP_ADDR	CONFIG_NET_CONFIG_PEER_IPV4_ADDR
#else
#define NATS_PEER_IP_ADDR	"192.168.0.2"
#endif /* CONFIG_NET_CONFIG_PEER_IPV4_ADDR */

#endif

/* DNS API */
#define DNS_PORT		53
#define DNS_SLEEP_MSECS		400

/* Default server */
#define DEFAULT_PORT		4222

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

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

	_sockaddr->sa_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) {
			LOG_ERR("Invalid IP address: %s", log_strdup(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;
}

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

	LOG_INF("Initializing network");

	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_IPV4) && defined(CONFIG_NET_DHCPV4)
	net_dhcpv4_start(iface);

	/* delay so DHCPv4 can assign IP */
	/* TODO: add a timeout/retry */
	LOG_INF("Waiting for DHCP ...");
	do {
		k_sleep(K_SECONDS(1));
	} while (net_ipv4_is_addr_unspecified(&iface->dhcpv4.requested_ip));

	LOG_INF("Done!");

	/* TODO: add a timeout */
	LOG_INF("Waiting for IP assginment ...");
	do {
		k_sleep(K_SECONDS(1));
	} while (!net_ipv4_is_my_addr(&iface->dhcpv4.requested_ip));

	LOG_INF("Done!");
#else
	struct sockaddr addr;

	if (in_addr_set(NATS_AF_INET, NATS_LOCAL_IP_ADDR, 0,
			  &addr) < 0) {
		LOG_ERR("Invalid IP address: %s",
			NATS_LOCAL_IP_ADDR);
	}

#if defined(CONFIG_NET_IPV6)
	net_if_ipv6_addr_add(iface,
			     &net_sin6(&addr)->sin6_addr,
			     NET_ADDR_MANUAL, 0);
#else
	net_if_ipv4_addr_add(iface,
			     &net_sin(&addr)->sin_addr,
			     NET_ADDR_MANUAL, 0);
#endif
#endif /* CONFIG_NET_IPV6 && CONFIG_NET_DHCPV6 */
}

static bool read_led(void)
{
	u32_t led = 0U;
	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(const struct nats *nats,
		      const struct nats_msg *msg,
		      bool state)
{
	char *pubstate;
	int ret;

	if (!led0) {
		fake_led = state;
	} else {
		gpio_pin_write(led0, LED_PIN, !state);
	}

	pubstate = state ? "on" : "off";
	ret = nats_publish(nats, "led0", 0, msg->reply_to, 0,
			   pubstate, strlen(pubstate));
	if (ret < 0) {
		printk("Failed to publish: %d\n", ret);
	} else {
		printk("*** Turning LED %s\n", pubstate);
	}
}

static int on_msg_received(const struct nats *nats,
			   const struct nats_msg *msg)
{
	if (!strcmp(msg->subject, "led0")) {
		if (msg->payload_len == 2 && !strcmp(msg->payload, "on")) {
			write_led(nats, msg, true);
			return 0;
		}

		if (msg->payload_len == 3 && !strcmp(msg->payload, "off")) {
			write_led(nats, msg, false);
			return 0;
		}

		if (msg->payload_len == 6 && !strcmp(msg->payload, "toggle")) {
			write_led(nats, msg, !read_led());
			return 0;
		}

		return -EINVAL;
	}

	return -ENOENT;
}

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

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

static int connect(struct nats *nats, u16_t port)
{
#if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_DHCPV4)
	struct net_if *iface;
#endif
	struct sockaddr dst_addr, src_addr;
	int ret;

	LOG_INF("Connecting...");

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

#if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_DHCPV6)
	/* TODO: IPV6 DHCP */
#elif defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_DHCPV4)
	iface = net_if_get_default();

	net_ipaddr_copy(&net_sin(&src_addr)->sin_addr,
			&iface->dhcpv4.requested_ip);
	ret = in_addr_set(NATS_AF_INET, NULL, 0, &src_addr);
#else
	ret = in_addr_set(NATS_AF_INET, NATS_LOCAL_IP_ADDR,
			  0, &src_addr);
	if (ret < 0) {
		goto connect_exit;
	}
#endif

	ret = in_addr_set(NATS_AF_INET, NATS_PEER_IP_ADDR,
			  port, &dst_addr);
	if (ret < 0) {
		goto connect_exit;
	}

	ret = net_context_bind(nats->conn, &src_addr,
			       sizeof(struct NATS_SOCKADDR_IN));
	if (ret < 0) {
		LOG_DBG("Could not bind to local address: %d", -ret);
		goto connect_exit;
	}

	ret = nats_connect(nats, &dst_addr, sizeof(struct NATS_SOCKADDR_IN));
	if (!ret) {
		return 0;
	}

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

static void nats_client(void)
{
	struct nats nats = {
		.on_message = on_msg_received
	};

	LOG_INF("NATS Client Sample");

	initialize_network();
	initialize_hardware();

	if (connect(&nats, DEFAULT_PORT) < 0) {
		panic("Could not connect to NATS server");
	}

	if (nats_subscribe(&nats, "led0", 0, NULL, 0,
			   "sub132984012384098", 0) < 0) {
		panic("Could not subscribe to `led0` topic");
	}
}

void main(void)
{
	nats_client();
}
