/**
 * Copyright (c) 2018 Texas Instruments, Incorporated
 *
 * SPDX-License-Identifier: Apache-2.0
 */

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

#include <zephyr.h>
#include <kernel.h>
#include <device.h>
#include <net/net_if.h>
#include <net/wifi_mgmt.h>
#include <net/net_offload.h>
#ifdef CONFIG_NET_SOCKETS_OFFLOAD
#include <net/socket_offload.h>
#endif

#include <ti/drivers/net/wifi/wlan.h>
#include "simplelink_support.h"
#include "simplelink_sockets.h"

#define SCAN_RETRY_DELAY 2000  /* ms */
#define FC_TIMEOUT K_SECONDS(CONFIG_WIFI_SIMPLELINK_FAST_CONNECT_TIMEOUT)

#define SIMPLELINK_IPV4 0x1
#define SIMPLELINK_IPV6 0x2

struct simplelink_data {
	struct net_if *iface;
	unsigned char mac[6];

	/* Fields for scan API to emulate an asynchronous scan: */
	struct k_work_delayable work;
	scan_result_cb_t cb;
	int num_results_or_err;
	int scan_retries;
	bool initialized;
	uint8_t mask;
};

static struct simplelink_data simplelink_data;
static K_SEM_DEFINE(ip_acquired, 0, 1);

/* Handle connection events from the SimpleLink Event Handlers: */
static void simplelink_wifi_cb(uint32_t event, struct sl_connect_state *conn)
{
	int status;

	/*
	 * Once Zephyr wifi_mgmt wifi_status codes are defined, will need
	 * to map from SimpleLink error codes.  For now, just return -EIO.
	 */
	status = (conn->error ? -EIO : 0);

	switch (event) {
	case SL_WLAN_EVENT_CONNECT:
		/* Only get this event if connect succeeds: */
		wifi_mgmt_raise_connect_result_event(simplelink_data.iface,
						     status);
		break;

	case SL_WLAN_EVENT_DISCONNECT:
		/* Could be during a connect, disconnect, or async error: */
		wifi_mgmt_raise_disconnect_result_event(simplelink_data.iface,
							status);
		break;

	case SIMPLELINK_WIFI_CB_IPACQUIRED:
		simplelink_data.mask &= ~SIMPLELINK_IPV4;
		if ((simplelink_data.mask == 0) &&
			(!simplelink_data.initialized)) {
			simplelink_data.initialized = true;
			k_sem_give(&ip_acquired);
		}
		break;

	case SIMPLELINK_WIFI_CB_IPV6ACQUIRED:
		simplelink_data.mask &= ~SIMPLELINK_IPV6;
		if ((simplelink_data.mask == 0) &&
			(!simplelink_data.initialized)) {
			simplelink_data.initialized = true;
			k_sem_give(&ip_acquired);
		}
		break;

	default:
		LOG_DBG("Unrecognized mgmt event: 0x%x", event);
		break;
	}
}

static void simplelink_scan_work_handler(struct k_work *work)
{
	if (simplelink_data.num_results_or_err > 0) {
		int index = 0;
		struct wifi_scan_result scan_result;

		/* Iterate over the table, and call the scan_result callback. */
		while (index < simplelink_data.num_results_or_err) {
			z_simplelink_get_scan_result(index, &scan_result);
			simplelink_data.cb(simplelink_data.iface, 0,
					   &scan_result);
			/* Yield, to ensure notifications get delivered:  */
			k_yield();
			index++;
		}

		/* Sending a NULL entry indicates e/o results, and
		 * triggers the NET_EVENT_WIFI_SCAN_DONE event:
		 */
		simplelink_data.cb(simplelink_data.iface, 0, NULL);

	} else if ((simplelink_data.num_results_or_err ==
		    SL_ERROR_WLAN_GET_NETWORK_LIST_EAGAIN) &&
		   (simplelink_data.scan_retries++ <
		    CONFIG_WIFI_SIMPLELINK_MAX_SCAN_RETRIES)) {
		int32_t delay;

		/* Try again: */
		simplelink_data.num_results_or_err = z_simplelink_start_scan();
		simplelink_data.scan_retries++;
		delay = (simplelink_data.num_results_or_err > 0 ? 0 :
			 SCAN_RETRY_DELAY);
		if (delay > 0) {
			LOG_DBG("Retrying scan...");
		}
		k_work_reschedule(&simplelink_data.work, K_MSEC(delay));

	} else {
		/* Encountered an error, or max retries exceeded: */
		LOG_ERR("Scan failed: retries: %d; err: %d",
			simplelink_data.scan_retries,
			simplelink_data.num_results_or_err);
		simplelink_data.cb(simplelink_data.iface, -EIO, NULL);
	}
}

static int simplelink_mgmt_scan(const struct device *dev, scan_result_cb_t cb)
{
	int err;
	int status;

	/* Cancel any previous scan processing in progress: */
	k_work_cancel_delayable(&simplelink_data.work);

	/* "Request" the scan: */
	err = z_simplelink_start_scan();

	/* Now, launch a delayed work handler to do retries and reporting.
	 * Indicate (to the work handler) either a positive number of results
	 * already returned, or indicate a retry is required:
	 */
	if ((err > 0) || (err == SL_ERROR_WLAN_GET_NETWORK_LIST_EAGAIN)) {
		int32_t delay = (err > 0 ? 0 : SCAN_RETRY_DELAY);

		/* Store for later reference by delayed work handler: */
		simplelink_data.cb = cb;
		simplelink_data.num_results_or_err = err;
		simplelink_data.scan_retries = 0;

		k_work_reschedule(&simplelink_data.work, K_MSEC(delay));
		status = 0;
	} else {
		status = -EIO;
	}

	return status;
}

static int simplelink_mgmt_connect(const struct device *dev,
				   struct wifi_connect_req_params *params)
{
	int ret;

	ret = z_simplelink_connect(params);

	return ret ? -EIO : ret;
}

static int simplelink_mgmt_disconnect(const struct device *dev)
{
	int ret;

	ret = z_simplelink_disconnect();

	return ret ? -EIO : ret;
}

static int simplelink_dummy_get(sa_family_t family,
				enum net_sock_type type,
				enum net_ip_protocol ip_proto,
				struct net_context **context)
{

	LOG_ERR("NET_SOCKETS_OFFLOAD must be configured for this driver");

	return -1;
}

/* Placeholders, until Zephyr IP stack updated to handle a NULL net_offload */
static struct net_offload simplelink_offload = {
	.get	       = simplelink_dummy_get,
	.bind	       = NULL,
	.listen	       = NULL,
	.connect       = NULL,
	.accept	       = NULL,
	.send	       = NULL,
	.sendto	       = NULL,
	.recv	       = NULL,
	.put	       = NULL,
};

static void simplelink_iface_init(struct net_if *iface)
{
	int ret;

	simplelink_data.iface = iface;
	simplelink_data.mask = 0;

	simplelink_data.mask |= IS_ENABLED(CONFIG_NET_IPV4) ?
		SIMPLELINK_IPV4 : 0;
	simplelink_data.mask |= IS_ENABLED(CONFIG_NET_IPV6) ?
		SIMPLELINK_IPV6 : 0;

	/* Direct socket offload used instead of net offload: */
	iface->if_dev->offload = &simplelink_offload;

	/* Initialize and configure NWP to defaults: */
	ret = z_simplelink_init(simplelink_wifi_cb);
	if (ret) {
		LOG_ERR("z_simplelink_init failed!");
		return;
	}

	ret = k_sem_take(&ip_acquired, FC_TIMEOUT);
	if (ret < 0) {
		simplelink_data.initialized = false;
		LOG_ERR("FastConnect timed out connecting to previous AP.");
		LOG_ERR("Please re-establish WiFi connection.");
	}

	/* Grab our MAC address: */
	z_simplelink_get_mac(simplelink_data.mac);

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

	net_if_set_link_addr(iface, simplelink_data.mac,
			     sizeof(simplelink_data.mac),
			     NET_LINK_ETHERNET);

#ifdef CONFIG_NET_SOCKETS_OFFLOAD
	/* Direct socket offload: */
	socket_offload_dns_register(&simplelink_dns_ops);
	simplelink_sockets_init();
#endif

}

static const struct net_wifi_mgmt_offload simplelink_api = {
	.iface_api.init = simplelink_iface_init,
	.scan		= simplelink_mgmt_scan,
	.connect	= simplelink_mgmt_connect,
	.disconnect	= simplelink_mgmt_disconnect,
};

static int simplelink_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	/* We use system workqueue to deal with scan retries: */
	k_work_init_delayable(&simplelink_data.work,
			      simplelink_scan_work_handler);

	LOG_DBG("SimpleLink driver Initialized");

	return 0;
}

NET_DEVICE_OFFLOAD_INIT(simplelink, CONFIG_WIFI_SIMPLELINK_NAME,
			simplelink_init, NULL,
			&simplelink_data, NULL,
			CONFIG_WIFI_INIT_PRIORITY, &simplelink_api,
			CONFIG_WIFI_SIMPLELINK_MAX_PACKET_SIZE);
