/*
 * Copyright (c) 2019 Linumiz
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <logging/log.h>
LOG_MODULE_REGISTER(wifi_eswifi, CONFIG_WIFI_LOG_LEVEL);

#include <zephyr.h>
#include <kernel.h>
#include <device.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#include "eswifi.h"
#include <net/net_pkt.h>

static int __stop_socket(struct eswifi_dev *eswifi,
			 struct eswifi_off_socket *socket)
{
	char cmd_srv[] = "P5=0\r";
	char cmd_cli[] = "P6=0\r";

	LOG_DBG("Stopping socket %d", socket->index);
	if (socket->state != ESWIFI_SOCKET_STATE_CONNECTED) {
		return 0;
	}

	socket->state = ESWIFI_SOCKET_STATE_NONE;
	return eswifi_at_cmd(eswifi, socket->is_server ? cmd_srv : cmd_cli);
}

static int __read_data(struct eswifi_dev *eswifi, size_t len, char **data)
{
	char cmd[] = "R0\r";
	char size[] = "R1=9999\r";
	char timeout[] = "R2=30000\r";
	int ret;

	/* Set max read size */
	snprintf(size, sizeof(size), "R1=%u\r", len);
	ret = eswifi_at_cmd(eswifi, size);
	if (ret < 0) {
		LOG_ERR("Unable to set read size");
		return -EIO;
	}

	/* Set timeout */
	snprintf(timeout, sizeof(timeout), "R2=%u\r", 30); /* 30 ms */
	ret = eswifi_at_cmd(eswifi, timeout);
	if (ret < 0) {
		LOG_ERR("Unable to set timeout");
		return -EIO;
	}

	return eswifi_at_cmd_rsp(eswifi, cmd, data);
}

int __eswifi_bind(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket,
		      const struct sockaddr *addr, socklen_t addrlen)
{
	int err;

	if (addr->sa_family != AF_INET) {
		LOG_ERR("Only AF_INET is supported!");
		return -EPFNOSUPPORT;
	}

	__select_socket(eswifi, socket->index);
	socket->port = sys_be16_to_cpu(net_sin(addr)->sin_port);

	/* Set Local Port */
	snprintf(eswifi->buf, sizeof(eswifi->buf), "P2=%d\r", socket->port);
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to set local port");
		return -EIO;
	}

	return 0;
}

static void eswifi_off_read_work(struct k_work *work)
{
	struct eswifi_off_socket *socket;
	struct eswifi_dev *eswifi;
	struct net_pkt *pkt;
	int err, len;
	char *data;

	LOG_DBG("");

	socket = CONTAINER_OF(work, struct eswifi_off_socket, read_work);
	eswifi = eswifi_socket_to_dev(socket);

	eswifi_lock(eswifi);

	if ((socket->type == ESWIFI_TRANSPORT_TCP ||
	     socket->type == ESWIFI_TRANSPORT_TCP_SSL) &&
	     socket->state != ESWIFI_SOCKET_STATE_CONNECTED) {
		goto done;
	}

	__select_socket(eswifi, socket->index);

	len = __read_data(eswifi, 1460, &data); /* 1460 is max size */
	if (len < 0) {
		__stop_socket(eswifi, socket);
		goto done;
	} else if (!len || !socket->recv_cb) {
		goto done;
	}

	LOG_DBG("payload sz = %d", len);

	pkt = net_pkt_rx_alloc_with_buffer(eswifi->iface, len,
					   AF_UNSPEC, 0, K_NO_WAIT);
	if (!pkt) {
		LOG_ERR("Cannot allocate rx packet");
		goto done;
	}

	if (net_pkt_write(pkt, data, len) < 0) {
		LOG_WRN("Incomplete buffer copy");
	}

	eswifi_unlock(eswifi);

	net_pkt_cursor_init(pkt);
	socket->recv_cb(socket->context, pkt,
			NULL, NULL, 0, socket->recv_data);

	eswifi_lock(eswifi);

	k_sem_give(&socket->read_sem);
	k_yield();

done:
	err = k_delayed_work_submit_to_queue(&eswifi->work_q,
					     &socket->read_work,
					     K_MSEC(500));
	if (err) {
		LOG_ERR("Rescheduling socket read error");
	}

	eswifi_unlock(eswifi);
}

int __eswifi_off_start_client(struct eswifi_dev *eswifi,
			      struct eswifi_off_socket *socket)
{
	struct sockaddr *addr = &socket->peer_addr;
	struct in_addr *sin_addr = &net_sin(addr)->sin_addr;
	int err;

	LOG_DBG("");

	__select_socket(eswifi, socket->index);

	/* Set Remote IP */
	snprintf(eswifi->buf, sizeof(eswifi->buf), "P3=%u.%u.%u.%u\r",
		 sin_addr->s4_addr[0], sin_addr->s4_addr[1],
		 sin_addr->s4_addr[2], sin_addr->s4_addr[3]);

	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to set remote ip");
		return -EIO;
	}

	/* Set Remote Port */
	snprintf(eswifi->buf, sizeof(eswifi->buf), "P4=%d\r",
		(u16_t)sys_be16_to_cpu(net_sin(addr)->sin_port));
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to set remote port");
		return -EIO;
	}

	/* Start TCP/UDP client */
	snprintf(eswifi->buf, sizeof(eswifi->buf), "P6=1\r");
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to start TCP/UDP client");
		return -EIO;
	}

	return 0;
}

int __eswifi_accept(struct eswifi_dev *eswifi, struct eswifi_off_socket *socket)
{
	char cmd[] = "P5=1\r";

	if (socket->state != ESWIFI_SOCKET_STATE_NONE) {
		/* we can only handle one connection at a time */
		return -EBUSY;
	}

	__select_socket(eswifi, socket->index);

	/* Start TCP Server */
	if (eswifi_at_cmd(eswifi, cmd) < 0) {
		LOG_ERR("Unable to start TCP server");
		return -EIO;
	}

	LOG_DBG("TCP Server started");
	socket->state = ESWIFI_SOCKET_STATE_ACCEPTING;

	return 0;
}

int __eswifi_socket_free(struct eswifi_dev *eswifi,
			 struct eswifi_off_socket *socket)
{
	if ((socket->type == ESWIFI_TRANSPORT_TCP ||
	     socket->type == ESWIFI_TRANSPORT_TCP_SSL) &&
	     socket->state != ESWIFI_SOCKET_STATE_CONNECTED)
		return -ENOTCONN;

	__select_socket(eswifi, socket->index);
	k_delayed_work_cancel(&socket->read_work);

	__select_socket(eswifi, socket->index);
	__stop_socket(eswifi, socket);

	return 0;
}

int __eswifi_socket_new(struct eswifi_dev *eswifi, int family, int type,
			int proto, void *context)
{
	struct eswifi_off_socket *socket = NULL;
	int err, i;

	LOG_DBG("");

	if (family != AF_INET) {
		LOG_ERR("Only AF_INET is supported!");
		return -EPFNOSUPPORT;
	}

	/* pickup available socket */
	for (i = 0; i < ESWIFI_OFFLOAD_MAX_SOCKETS; i++) {
		if (!eswifi->socket[i].context) {
			socket = &eswifi->socket[i];
			socket->index = i;
			socket->context = context;
			break;
		}
	}

	if (!socket) {
		LOG_ERR("No socket resource available");
		return -ENOMEM;
	}

	if (IS_ENABLED(CONFIG_NET_SOCKETS_SOCKOPT_TLS) &&
	    proto >= IPPROTO_TLS_1_0 && proto <= IPPROTO_TLS_1_2) {
		socket->type = ESWIFI_TRANSPORT_TCP_SSL;
	} else if (proto == IPPROTO_TCP) {
		socket->type = ESWIFI_TRANSPORT_TCP;
	} else if (proto == IPPROTO_UDP) {
		socket->type = ESWIFI_TRANSPORT_UDP;
	} else {
		LOG_ERR("Only TCP & UDP is supported");
		return -EPFNOSUPPORT;
	}

	err = __select_socket(eswifi, socket->index);
	if (err < 0) {
		LOG_ERR("Unable to select socket %u", socket->index);
		return -EIO;
	}

	snprintf(eswifi->buf, sizeof(eswifi->buf), "P1=%d\r", socket->type);
	err = eswifi_at_cmd(eswifi, eswifi->buf);
	if (err < 0) {
		LOG_ERR("Unable to set transport protocol");
		return -EIO;
	}

	k_delayed_work_init(&socket->read_work, eswifi_off_read_work);
	socket->usage = 1;
	LOG_DBG("Socket index %d", socket->index);

	return socket->index;
}
