/**
 * Copyright (c) 2018 Linaro
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#if defined(CONFIG_WIFI_ESWIFI_BUS_UART)
#define DT_DRV_COMPAT inventek_eswifi_uart
#else
#define DT_DRV_COMPAT inventek_eswifi
#endif

#include "eswifi_log.h"
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

#include <zephyr.h>
#include <kernel.h>
#include <device.h>
#include <string.h>
#include <errno.h>
#include <drivers/gpio.h>
#include <net/net_pkt.h>
#include <net/net_if.h>
#include <net/net_context.h>
#include <net/net_offload.h>
#include <net/wifi_mgmt.h>

#include <net/ethernet.h>
#include <net_private.h>
#include <net/net_core.h>
#include <net/net_pkt.h>

#include <stdio.h>
#include <stdlib.h>

#include <sys/printk.h>

#include "eswifi.h"

#define ESWIFI_WORKQUEUE_STACK_SIZE 1024
K_KERNEL_STACK_DEFINE(eswifi_work_q_stack, ESWIFI_WORKQUEUE_STACK_SIZE);

static struct eswifi_dev eswifi0; /* static instance */

static int eswifi_reset(struct eswifi_dev *eswifi)
{
	gpio_pin_set(eswifi->resetn.dev, eswifi->resetn.pin, 0);
	k_sleep(K_MSEC(10));
	gpio_pin_set(eswifi->resetn.dev, eswifi->resetn.pin, 1);
	gpio_pin_set(eswifi->wakeup.dev, eswifi->wakeup.pin, 1);
	k_sleep(K_MSEC(500));

	/* fetch the cursor */
	return eswifi_request(eswifi, NULL, 0, eswifi->buf,
			      sizeof(eswifi->buf));
}

static inline int __parse_ssid(char *str, char *ssid)
{
	int i = 0;

	/* fmt => "SSID" */

	if (*str != '"') {
		return 0;
	}
	str++;

	while (*str && (*str != '"') && i < WIFI_SSID_MAX_LEN) {
		ssid[i++] = *str++;
	}

	if (*str != '"') {
		return 0;
	}

	return i;
}

static void __parse_scan_res(char *str, struct wifi_scan_result *res)
{
	int field = 0;

	/* fmt => #001,"SSID",MACADDR,RSSI,BITRATE,MODE,SECURITY,BAND,CHANNEL */

	while (*str) {
		if (*str != ',') {
			str++;
			continue;
		}

		if (!*++str) {
			break;
		}

		switch (++field) {
		case 1: /* SSID */
			res->ssid_length = __parse_ssid(str, res->ssid);
			str += res->ssid_length;
			break;
		case 2: /* mac addr */
			break;
		case 3: /* RSSI */
			res->rssi = atoi(str);
			break;
		case 4: /* bitrate */
			break;
		case 5: /* mode */
			break;
		case 6: /* security */
			if (!strncmp(str, "Open", 4)) {
				res->security = WIFI_SECURITY_TYPE_NONE;
			} else {
				res->security = WIFI_SECURITY_TYPE_PSK;
			}
			break;
		case 7: /* band */
			break;
		case 8: /* channel */
			res->channel = atoi(str);
			break;
		}

	}
}

int eswifi_at_cmd_rsp(struct eswifi_dev *eswifi, char *cmd, char **rsp)
{
	const char startstr[] = "\r\n";
	const char endstr[] = "\r\nOK\r\n>";
	int i, len, rsplen = -EINVAL;

	len = eswifi_request(eswifi, cmd, strlen(cmd), eswifi->buf,
			     sizeof(eswifi->buf));
	if (len < 0) {
		return -EIO;
	}

	/*
	 * Check response, format should be "\r\n[DATA]\r\nOK\r\n>"
	 * Data is in arbitrary format (not only ASCII)
	 */

	/* Check start characters */
	if (strncmp(eswifi->buf, startstr, strlen(startstr))) {
		return -EINVAL;
	}

	if (len < sizeof(endstr) - 1 + sizeof(startstr) - 1) {
		return -EINVAL;
	}

	/* Check end characters */
	for (i = len - sizeof(endstr); i > 0; i--) {
		if (!strncmp(&eswifi->buf[i], endstr, 7)) {
			if (rsp) {
				eswifi->buf[i] = '\0';
				*rsp = &eswifi->buf[2];
				rsplen = &eswifi->buf[i] - *rsp;
			} else {
				rsplen = 0;
			}
			break;
		}
	}

	return rsplen;
}

int eswifi_at_cmd(struct eswifi_dev *eswifi, char *cmd)
{
	return eswifi_at_cmd_rsp(eswifi, cmd, NULL);
}

struct eswifi_dev *eswifi_by_iface_idx(uint8_t iface)
{
	/* only one instance */
	LOG_DBG("%d", iface);
	return &eswifi0;
}

static int __parse_ipv4_address(char *str, char *ssid, uint8_t ip[4])
{
	int byte = -1;

	/* fmt => [JOIN   ] SSID,192.168.2.18,0,0 */
	while (*str && byte < 4) {
		if (byte == -1) {
			if (!strncmp(str, ssid, strlen(ssid))) {
				byte = 0;
				str += strlen(ssid);
			}
			str++;
			continue;
		}

		ip[byte++] = atoi(str);
		while (*str && (*str++ != '.')) {
		}
	}

	return 0;
}

static void eswifi_scan(struct eswifi_dev *eswifi)
{
	char cmd[] = "F0\r";
	char *data;
	int i, ret;

	LOG_DBG("");

	eswifi_lock(eswifi);

	ret = eswifi_at_cmd_rsp(eswifi, cmd, &data);
	if (ret < 0) {
		eswifi->scan_cb(eswifi->iface, -EIO, NULL);
		eswifi_unlock(eswifi);
		return;
	}

	for (i = 0; i < ret; i++) {
		if (data[i] == '#') {
			struct wifi_scan_result res = {0};

			__parse_scan_res(&data[i], &res);

			eswifi->scan_cb(eswifi->iface, 0, &res);
			k_yield();

			while (data[i] && data[i] != '\n') {
				i++;
			}
		}
	}

	/* WiFi scan is done. */
	eswifi->scan_cb(eswifi->iface, 0, NULL);

	eswifi_unlock(eswifi);
}

static int eswifi_connect(struct eswifi_dev *eswifi)
{
	char connect[] = "C0\r";
	struct in_addr addr;
	char *rsp;
	int err;

	LOG_DBG("Connecting to %s (pass=%s)", log_strdup(eswifi->sta.ssid),
		log_strdup(eswifi->sta.pass));

	eswifi_lock(eswifi);

	/* Set SSID */
	snprintk(eswifi->buf, sizeof(eswifi->buf), "C1=%s\r", eswifi->sta.ssid);
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to set SSID");
		goto error;
	}

	/* Set passphrase */
	snprintk(eswifi->buf, sizeof(eswifi->buf), "C2=%s\r", eswifi->sta.pass);
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to set passphrase");
		goto error;
	}

	/* Set Security type */
	snprintk(eswifi->buf, sizeof(eswifi->buf), "C3=%u\r",
		 eswifi->sta.security);
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to configure security");
		goto error;
	}

	/* Join Network */
	err = eswifi_at_cmd_rsp(eswifi, connect, &rsp);
	if (err < 0) {
		LOG_ERR("Unable to join network");
		goto error;
	}

	/* Any IP assigned ? (dhcp offload or manually) */
	err = __parse_ipv4_address(rsp, eswifi->sta.ssid,
				   (uint8_t *)&addr.s4_addr);
	if (err < 0) {
		LOG_ERR("Unable to retrieve IP address");
		goto error;
	}

	LOG_DBG("ip = %d.%d.%d.%d", addr.s4_addr[0], addr.s4_addr[1],
		   addr.s4_addr[2], addr.s4_addr[3]);

	net_if_ipv4_addr_add(eswifi->iface, &addr, NET_ADDR_DHCP, 0);

	LOG_DBG("Connected!");

	eswifi_unlock(eswifi);
	return 0;

error:
	eswifi_unlock(eswifi);
	return -EIO;
}

static int eswifi_disconnect(struct eswifi_dev *eswifi)
{
	char disconnect[] = "CD\r";
	int err;

	LOG_DBG("");

	eswifi_lock(eswifi);

	err = eswifi_at_cmd(eswifi, disconnect);
	if (err < 0) {
		LOG_ERR("Unable to disconnect network");
		err = -EIO;
	}

	eswifi_unlock(eswifi);

	return err;
}

static void eswifi_request_work(struct k_work *item)
{
	struct eswifi_dev *eswifi;
	int err;

	LOG_DBG("");

	eswifi = CONTAINER_OF(item, struct eswifi_dev, request_work);

	switch (eswifi->req) {
	case ESWIFI_REQ_CONNECT:
		err = eswifi_connect(eswifi);
		wifi_mgmt_raise_connect_result_event(eswifi->iface, err);
		break;
	case ESWIFI_REQ_DISCONNECT:
		err = eswifi_disconnect(eswifi);
		wifi_mgmt_raise_disconnect_result_event(eswifi->iface, err);
		break;
	case ESWIFI_REQ_SCAN:
		eswifi_scan(eswifi);
		break;
	case ESWIFI_REQ_NONE:
	default:
		break;
	}
}

static int eswifi_get_mac_addr(struct eswifi_dev *eswifi, uint8_t addr[6])
{
	char cmd[] = "Z5\r";
	int ret, i, byte = 0;
	char *rsp;

	ret = eswifi_at_cmd_rsp(eswifi, cmd, &rsp);
	if (ret < 0) {
		return ret;
	}

	/* format is "ff:ff:ff:ff:ff:ff" */
	for (i = 0; i < ret && byte < 6; i++) {
		addr[byte++] = strtol(&rsp[i], NULL, 16);
		i += 2;
	}

	if (byte != 6) {
		return -EIO;
	}

	return 0;
}

static void eswifi_iface_init(struct net_if *iface)
{
	struct eswifi_dev *eswifi = &eswifi0;
	uint8_t mac[6];

	LOG_DBG("");

	eswifi_lock(eswifi);

	if (eswifi_reset(eswifi) < 0) {
		LOG_ERR("Unable to reset device");
		return;
	}

	if (eswifi_get_mac_addr(eswifi, mac) < 0) {
		LOG_ERR("Unable to read MAC address");
		return;
	}

	LOG_DBG("MAC Address %02X:%02X:%02X:%02X:%02X:%02X",
		   mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

	memcpy(eswifi->mac, mac, sizeof(eswifi->mac));
	net_if_set_link_addr(iface, eswifi->mac, sizeof(eswifi->mac),
			     NET_LINK_ETHERNET);

	eswifi->iface = iface;

	eswifi_unlock(eswifi);

	eswifi_offload_init(eswifi);
#if defined(CONFIG_NET_SOCKETS_OFFLOAD)
	eswifi_socket_offload_init(eswifi);
#endif

}

static int eswifi_mgmt_scan(const struct device *dev, scan_result_cb_t cb)
{
	struct eswifi_dev *eswifi = dev->data;

	LOG_DBG("");

	eswifi_lock(eswifi);

	eswifi->scan_cb = cb;
	eswifi->req = ESWIFI_REQ_SCAN;
	k_work_submit_to_queue(&eswifi->work_q, &eswifi->request_work);

	eswifi_unlock(eswifi);

	return 0;
}

static int eswifi_mgmt_disconnect(const struct device *dev)
{
	struct eswifi_dev *eswifi = dev->data;

	LOG_DBG("");

	eswifi_lock(eswifi);

	eswifi->req = ESWIFI_REQ_DISCONNECT;
	k_work_submit_to_queue(&eswifi->work_q, &eswifi->request_work);

	eswifi_unlock(eswifi);

	return 0;
}

static int __eswifi_sta_config(struct eswifi_dev *eswifi,
			       struct wifi_connect_req_params *params)
{
	memcpy(eswifi->sta.ssid, params->ssid, params->ssid_length);
	eswifi->sta.ssid[params->ssid_length] = '\0';

	switch (params->security) {
	case WIFI_SECURITY_TYPE_NONE:
		eswifi->sta.pass[0] = '\0';
		eswifi->sta.security = ESWIFI_SEC_OPEN;
		break;
	case WIFI_SECURITY_TYPE_PSK:
		memcpy(eswifi->sta.pass, params->psk, params->psk_length);
		eswifi->sta.pass[params->psk_length] = '\0';
		eswifi->sta.security = ESWIFI_SEC_WPA2_MIXED;
		break;
	default:
		return -EINVAL;
	}

	if (params->channel == WIFI_CHANNEL_ANY) {
		eswifi->sta.channel = 0U;
	} else {
		eswifi->sta.channel = params->channel;
	}

	return 0;
}

static int eswifi_mgmt_connect(const struct device *dev,
			       struct wifi_connect_req_params *params)
{
	struct eswifi_dev *eswifi = dev->data;
	int err;

	LOG_DBG("");

	eswifi_lock(eswifi);

	err = __eswifi_sta_config(eswifi, params);
	if (!err) {
		eswifi->req = ESWIFI_REQ_CONNECT;
		k_work_submit_to_queue(&eswifi->work_q,
				       &eswifi->request_work);
	}

	eswifi_unlock(eswifi);

	return err;
}

void eswifi_async_msg(struct eswifi_dev *eswifi, char *msg, size_t len)
{
	eswifi_offload_async_msg(eswifi, msg, len);
}

#if defined(CONFIG_NET_IPV4)
static int eswifi_mgmt_ap_enable(const struct device *dev,
				 struct wifi_connect_req_params *params)
{
	struct eswifi_dev *eswifi = dev->data;
	struct net_if_ipv4 *ipv4 = eswifi->iface->config.ip.ipv4;
	struct net_if_addr *unicast = NULL;
	int err = -EIO, i;

	LOG_DBG("");

	eswifi_lock(eswifi);

	if (eswifi->role == ESWIFI_ROLE_AP) {
		err = -EALREADY;
		goto error;
	}

	err = __eswifi_sta_config(eswifi, params);
	if (err) {
		goto error;
	}

	/* security */
	snprintk(eswifi->buf, sizeof(eswifi->buf), "A1=%u\r",
		 eswifi->sta.security);
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to set Security");
		goto error;
	}

	/* Passkey */
	if (eswifi->sta.security != ESWIFI_SEC_OPEN) {
		snprintk(eswifi->buf, sizeof(eswifi->buf), "A2=%s\r",
			 eswifi->sta.pass);
		err = eswifi_at_cmd(eswifi, eswifi->buf);
		if (err < 0) {
			LOG_ERR("Unable to set passkey");
			goto error;
		}
	}

	/* Set SSID (0=no MAC, 1=append MAC) */
	snprintk(eswifi->buf, sizeof(eswifi->buf), "AS=0,%s\r",
		 eswifi->sta.ssid);
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to set SSID");
		goto error;
	}

	/* Set Channel */
	snprintk(eswifi->buf, sizeof(eswifi->buf), "AC=%u\r",
		 eswifi->sta.channel);
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to set Channel");
		goto error;
	}

	/* Set IP Address */
	for (i = 0; ipv4 && i < NET_IF_MAX_IPV4_ADDR; i++) {
		if (ipv4->unicast[i].is_used) {
			unicast = &ipv4->unicast[i];
			break;
		}
	}

	if (!unicast) {
		LOG_ERR("No IPv4 assigned for AP mode");
		err = -EADDRNOTAVAIL;
		goto error;
	}

	snprintk(eswifi->buf, sizeof(eswifi->buf), "Z6=%s\r",
		 net_sprint_ipv4_addr(&unicast->address.in_addr));
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to active access point");
		goto error;
	}

	/* Enable AP */
	snprintk(eswifi->buf, sizeof(eswifi->buf), "AD\r");
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to active access point");
		goto error;
	}

	eswifi->role = ESWIFI_ROLE_AP;

	eswifi_unlock(eswifi);
	return 0;
error:
	eswifi_unlock(eswifi);
	return err;
}
#else
static int eswifi_mgmt_ap_enable(const struct device *dev,
				 struct wifi_connect_req_params *params)
{
	LOG_ERR("IPv4 requested for AP mode");
	return -ENOTSUP;
}
#endif /* CONFIG_NET_IPV4 */

static int eswifi_mgmt_ap_disable(const struct device *dev)
{
	struct eswifi_dev *eswifi = dev->data;
	char cmd[] = "AE\r";
	int err;

	eswifi_lock(eswifi);

	err = eswifi_at_cmd(eswifi, cmd);
	if (err < 0) {
		eswifi_unlock(eswifi);
		return -EIO;
	}

	eswifi->role = ESWIFI_ROLE_CLIENT;

	eswifi_unlock(eswifi);

	return 0;
}

static int eswifi_init(const struct device *dev)
{
	struct eswifi_dev *eswifi = dev->data;

	LOG_DBG("");

	eswifi->role = ESWIFI_ROLE_CLIENT;
	k_mutex_init(&eswifi->mutex);

	eswifi->bus = eswifi_get_bus();
	eswifi->bus->init(eswifi);

	eswifi->resetn.dev = device_get_binding(
			DT_INST_GPIO_LABEL(0, resetn_gpios));
	if (!eswifi->resetn.dev) {
		LOG_ERR("Failed to initialize GPIO driver: %s",
			    DT_INST_GPIO_LABEL(0, resetn_gpios));
		return -ENODEV;
	}
	eswifi->resetn.pin = DT_INST_GPIO_PIN(0, resetn_gpios);
	gpio_pin_configure(eswifi->resetn.dev, eswifi->resetn.pin,
			   DT_INST_GPIO_FLAGS(0, resetn_gpios) |
			   GPIO_OUTPUT_INACTIVE);

	eswifi->wakeup.dev = device_get_binding(
			DT_INST_GPIO_LABEL(0, wakeup_gpios));
	if (!eswifi->wakeup.dev) {
		LOG_ERR("Failed to initialize GPIO driver: %s",
			    DT_INST_GPIO_LABEL(0, wakeup_gpios));
		return -ENODEV;
	}
	eswifi->wakeup.pin = DT_INST_GPIO_PIN(0, wakeup_gpios);
	gpio_pin_configure(eswifi->wakeup.dev, eswifi->wakeup.pin,
			   DT_INST_GPIO_FLAGS(0, wakeup_gpios) |
			   GPIO_OUTPUT_ACTIVE);

	k_work_queue_start(&eswifi->work_q, eswifi_work_q_stack,
			   K_KERNEL_STACK_SIZEOF(eswifi_work_q_stack),
			   CONFIG_SYSTEM_WORKQUEUE_PRIORITY - 1, NULL);

	k_work_init(&eswifi->request_work, eswifi_request_work);

	eswifi_shell_register(eswifi);

	return 0;
}

static const struct net_wifi_mgmt_offload eswifi_offload_api = {
	.iface_api.init = eswifi_iface_init,
	.scan		= eswifi_mgmt_scan,
	.connect	= eswifi_mgmt_connect,
	.disconnect	= eswifi_mgmt_disconnect,
	.ap_enable	= eswifi_mgmt_ap_enable,
	.ap_disable	= eswifi_mgmt_ap_disable,
};

NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, eswifi_init, NULL,
				  &eswifi0, NULL,
				  CONFIG_WIFI_INIT_PRIORITY,
				  &eswifi_offload_api,
				  1500);
