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

#if 1
#define SYS_LOG_DOMAIN "zoap-server"
#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
#define NET_LOG_ENABLED 1
#endif

#include <errno.h>

#include <zephyr.h>
#include <board.h>

#include <misc/byteorder.h>
#include <net/net_core.h>
#include <net/net_ip.h>
#include <net/nbuf.h>
#include <net/net_context.h>

#include <net_private.h>

#include <gpio.h>

#if defined(CONFIG_NET_L2_BLUETOOTH)
#include <bluetooth/bluetooth.h>
#include <gatt/ipss.h>
#endif

#include <net/zoap.h>
#include <net/zoap_link_format.h>

#define MY_COAP_PORT 5683

#define ALL_NODES_LOCAL_COAP_MCAST					\
	{ { { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xfd } } }

#define MY_IP6ADDR \
	{ { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }

#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 net_context *context;

static struct device *led0;

static const char led_on[] = "LED ON\n";
static const char led_off[] = "LED OFF\n";
static const char led_toggle_on[] = "LED Toggle ON\n";
static const char led_toggle_off[] = "LED Toggle OFF\n";

static bool fake_led;

static bool read_led(void)
{
	uint32_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;
		return;
	}

	gpio_pin_write(led0, LED_PIN, !led);
}

static int led_get(struct zoap_resource *resource,
		   struct zoap_packet *request,
		   const struct sockaddr *from)
{
	struct net_buf *buf, *frag;
	struct zoap_packet response;
	const char *str;
	uint8_t *payload;
	uint16_t len, id;
	int r;

	id = zoap_header_get_id(request);

	buf = net_nbuf_get_tx(context, K_FOREVER);
	if (!buf) {
		return -ENOMEM;
	}

	frag = net_nbuf_get_data(context, K_FOREVER);
	if (!frag) {
		return -ENOMEM;
	}

	net_buf_frag_add(buf, frag);

	r = zoap_packet_init(&response, buf);
	if (r < 0) {
		return -EINVAL;
	}

	/* FIXME: Could be that zoap_packet_init() sets some defaults */
	zoap_header_set_version(&response, 1);
	zoap_header_set_type(&response, ZOAP_TYPE_ACK);
	zoap_header_set_code(&response, ZOAP_RESPONSE_CODE_CONTENT);
	zoap_header_set_id(&response, id);

	payload = zoap_packet_get_payload(&response, &len);
	if (!payload) {
		return -EINVAL;
	}

	if (read_led()) {
		str = led_on;
		r = sizeof(led_on);
	} else {
		str = led_off;
		r = sizeof(led_off);
	}

	memcpy(payload, str, r);

	r = zoap_packet_set_used(&response, r);
	if (r) {
		return -EINVAL;
	}

	return net_context_sendto(buf, from, sizeof(struct sockaddr_in6),
				  NULL, 0, NULL, NULL);
}

static int led_post(struct zoap_resource *resource,
		    struct zoap_packet *request,
		    const struct sockaddr *from)
{
	struct net_buf *buf, *frag;
	struct zoap_packet response;
	const char *str;
	uint8_t *payload;
	uint16_t len, id;
	uint32_t led;
	int r;

	payload = zoap_packet_get_payload(request, &len);
	if (!payload) {
		printk("packet without payload");
		return -EINVAL;
	}

	id = zoap_header_get_id(request);

	buf = net_nbuf_get_tx(context, K_FOREVER);
	if (!buf) {
		return -ENOMEM;
	}

	frag = net_nbuf_get_data(context, K_FOREVER);
	if (!frag) {
		return -ENOMEM;
	}

	net_buf_frag_add(buf, frag);

	r = zoap_packet_init(&response, buf);
	if (r < 0) {
		return -EINVAL;
	}

	/* FIXME: Could be that zoap_packet_init() sets some defaults */
	zoap_header_set_version(&response, 1);
	zoap_header_set_type(&response, ZOAP_TYPE_ACK);
	zoap_header_set_code(&response, ZOAP_RESPONSE_CODE_CONTENT);
	zoap_header_set_id(&response, id);

	payload = zoap_packet_get_payload(&response, &len);
	if (!payload) {
		return -EINVAL;
	}

	led = read_led();

	led = !led;

	write_led(led);

	if (led) {
		str = led_toggle_on;
		r = sizeof(led_toggle_on);
	} else {
		str = led_toggle_off;
		r = sizeof(led_toggle_off);
	}

	memcpy(payload, str, r);

	r = zoap_packet_set_used(&response, r);
	if (r) {
		return -EINVAL;
	}

	return net_context_sendto(buf, from, sizeof(struct sockaddr_in6),
				  NULL, 0, NULL, NULL);
}

static int led_put(struct zoap_resource *resource,
		   struct zoap_packet *request,
		   const struct sockaddr *from)
{
	struct net_buf *buf, *frag;
	struct zoap_packet response;
	const char *str;
	uint8_t *payload;
	uint16_t len, id;
	uint32_t led;
	int r;

	payload = zoap_packet_get_payload(request, &len);
	if (!payload) {
		printk("packet without payload");
		return -EINVAL;
	}

	led = 0;
	if (len > 0 && payload[0] == '1') {
		led = 1;
	}

	id = zoap_header_get_id(request);

	buf = net_nbuf_get_tx(context, K_FOREVER);
	if (!buf) {
		return -ENOMEM;
	}

	frag = net_nbuf_get_data(context, K_FOREVER);
	if (!frag) {
		return -ENOMEM;
	}

	net_buf_frag_add(buf, frag);

	r = zoap_packet_init(&response, buf);
	if (r < 0) {
		return -EINVAL;
	}

	/* FIXME: Could be that zoap_packet_init() sets some defaults */
	zoap_header_set_version(&response, 1);
	zoap_header_set_type(&response, ZOAP_TYPE_ACK);
	zoap_header_set_code(&response, ZOAP_RESPONSE_CODE_CHANGED);
	zoap_header_set_id(&response, id);

	payload = zoap_packet_get_payload(&response, &len);
	if (!payload) {
		return -EINVAL;
	}

	write_led(led);

	if (led) {
		str = led_on;
		r = sizeof(led_on);
	} else {
		str = led_off;
		r = sizeof(led_off);
	}

	memcpy(payload, str, r);

	r = zoap_packet_set_used(&response, r);
	if (r) {
		return -EINVAL;
	}

	return net_context_sendto(buf, from, sizeof(struct sockaddr_in6),
				  NULL, 0, NULL, NULL);
}

static int dummy_get(struct zoap_resource *resource,
		     struct zoap_packet *request,
		     const struct sockaddr *from)
{
	static const char dummy_str[] = "Just a test\n";
	struct net_buf *buf, *frag;
	struct zoap_packet response;
	uint8_t *payload;
	uint16_t len, id;
	int r;

	id = zoap_header_get_id(request);

	buf = net_nbuf_get_tx(context, K_FOREVER);
	if (!buf) {
		return -ENOMEM;
	}

	frag = net_nbuf_get_data(context, K_FOREVER);
	if (!frag) {
		return -ENOMEM;
	}

	net_buf_frag_add(buf, frag);

	r = zoap_packet_init(&response, buf);
	if (r < 0) {
		return -EINVAL;
	}

	/* FIXME: Could be that zoap_packet_init() sets some defaults */
	zoap_header_set_version(&response, 1);
	zoap_header_set_type(&response, ZOAP_TYPE_ACK);
	zoap_header_set_code(&response, ZOAP_RESPONSE_CODE_CONTENT);
	zoap_header_set_id(&response, id);

	payload = zoap_packet_get_payload(&response, &len);
	if (!payload) {
		return -EINVAL;
	}

	memcpy(payload, dummy_str, sizeof(dummy_str));

	r = zoap_packet_set_used(&response, sizeof(dummy_str));
	if (r) {
		return -EINVAL;
	}

	return net_context_sendto(buf, from, sizeof(struct sockaddr_in6),
				  NULL, 0, NULL, NULL);
}

static const char * const led_default_path[] = { "led", NULL };
static const char * const led_default_attributes[] = {
	"title=\"LED\"",
	"rt=Text",
	NULL };

static const char * const dummy_path[] = { "dummy", NULL };
static const char * const dummy_attributes[] = {
	"title=\"Dummy\"",
	"rt=dummy",
	NULL };

static struct zoap_resource resources[] = {
	ZOAP_WELL_KNOWN_CORE_RESOURCE,
	{ .get = led_get,
	  .post = led_post,
	  .put = led_put,
	  .path = led_default_path,
	  .user_data = &((struct zoap_core_metadata) {
			  .attributes = led_default_attributes,
			}),
	},
	{ .get = dummy_get,
	  .path = dummy_path,
	  .user_data = &((struct zoap_core_metadata) {
			  .attributes = dummy_attributes,
			}),
	},
	{ },
};

static void udp_receive(struct net_context *context,
			struct net_buf *buf,
			int status,
			void *user_data)
{
	struct zoap_packet request;
	struct sockaddr_in6 from;
	int r, header_len;

	net_ipaddr_copy(&from.sin6_addr, &NET_IPV6_BUF(buf)->src);
	from.sin6_port = NET_UDP_BUF(buf)->src_port;
	from.sin6_family = AF_INET6;

	/*
	 * zoap expects that buffer->data starts at the
	 * beginning of the CoAP header
	 */
	header_len = net_nbuf_appdata(buf) - buf->frags->data;
	net_buf_pull(buf->frags, header_len);

	r = zoap_packet_parse(&request, buf);
	if (r < 0) {
		NET_ERR("Invalid data received (%d)\n", r);
		net_nbuf_unref(buf);
		return;
	}

	r = zoap_handle_request(&request, resources,
				(const struct sockaddr *) &from);

	net_nbuf_unref(buf);

	if (r < 0) {
		NET_ERR("No handler for such request (%d)\n", r);
		return;
	}
}

static bool join_coap_multicast_group(void)
{
	static struct in6_addr my_addr = MY_IP6ADDR;
	static struct sockaddr_in6 mcast_addr = {
		.sin6_family = AF_INET6,
		.sin6_addr = ALL_NODES_LOCAL_COAP_MCAST,
		.sin6_port = htons(MY_COAP_PORT) };
	struct net_if_mcast_addr *mcast;
	struct net_if_addr *ifaddr;
	struct net_if *iface;

	iface = net_if_get_default();
	if (!iface) {
		NET_ERR("Could not get te default interface\n");
		return false;
	}

	ifaddr = net_if_ipv6_addr_add(net_if_get_default(),
				      &my_addr, NET_ADDR_MANUAL, 0);
	ifaddr->addr_state = NET_ADDR_PREFERRED;

	mcast = net_if_ipv6_maddr_add(iface, &mcast_addr.sin6_addr);
	if (!mcast) {
		NET_ERR("Could not add multicast address to interface\n");
		return false;
	}

	return true;
}

void main(void)
{
	static struct sockaddr_in6 any_addr = {
		.sin6_family = AF_INET6,
		.sin6_addr = IN6ADDR_ANY_INIT,
		.sin6_port = htons(MY_COAP_PORT) };
	int r;

#if defined(CONFIG_NET_L2_BLUETOOTH)
	if (bt_enable(NULL)) {
		NET_ERR("Bluetooth init failed");
		return;
	}
	ipss_init();
	ipss_advertise();
#endif

	led0 = device_get_binding(LED_GPIO_NAME);
	/* Want it to be NULL if not available */

	if (led0) {
		gpio_pin_configure(led0, LED_PIN, GPIO_DIR_OUT);
	}

	if (!join_coap_multicast_group()) {
		NET_ERR("Could not join CoAP multicast group\n");
		return;
	}

	r = net_context_get(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, &context);
	if (r) {
		NET_ERR("Could not get an UDP context\n");
		return;
	}

	r = net_context_bind(context, (struct sockaddr *) &any_addr,
			     sizeof(any_addr));
	if (r) {
		NET_ERR("Could not bind the context\n");
		return;
	}

	r = net_context_recv(context, udp_receive, 0, NULL);
	if (r) {
		NET_ERR("Could not receive in the context\n");
		return;
	}
}
