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

#include <zephyr/init.h>

#include <zephyr/logging/log.h>
#include <zephyr/net/socket.h>
#include <zephyr/net/socket_service.h>
#include <zephyr/shell/shell_telnet.h>

#include "shell_telnet_protocol.h"

SHELL_TELNET_DEFINE(shell_transport_telnet);
SHELL_DEFINE(shell_telnet, CONFIG_SHELL_PROMPT_TELNET, &shell_transport_telnet,
	     CONFIG_SHELL_TELNET_LOG_MESSAGE_QUEUE_SIZE,
	     CONFIG_SHELL_TELNET_LOG_MESSAGE_QUEUE_TIMEOUT,
	     SHELL_FLAG_OLF_CRLF);

LOG_MODULE_REGISTER(shell_telnet, CONFIG_SHELL_TELNET_LOG_LEVEL);

struct shell_telnet *sh_telnet;

/* Various definitions mapping the TELNET service configuration options */
#define TELNET_PORT      CONFIG_SHELL_TELNET_PORT
#define TELNET_LINE_SIZE CONFIG_SHELL_TELNET_LINE_BUF_SIZE
#define TELNET_TIMEOUT   CONFIG_SHELL_TELNET_SEND_TIMEOUT

#define TELNET_MIN_COMMAND_LEN 2
#define TELNET_WILL_DO_COMMAND_LEN 3

#define SOCK_ID_IPV4_LISTEN 0
#define SOCK_ID_IPV6_LISTEN 1
#define SOCK_ID_CLIENT      2
#define SOCK_ID_MAX         3

/* Basic TELNET implementation. */

static void telnet_server_cb(struct k_work *work);
static int telnet_init(struct shell_telnet *ctx);

NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(telnet_server, NULL, telnet_server_cb,
				      SHELL_TELNET_POLLFD_COUNT);


static void telnet_end_client_connection(void)
{
	int ret;

	(void)zsock_close(sh_telnet->fds[SOCK_ID_CLIENT].fd);

	sh_telnet->fds[SOCK_ID_CLIENT].fd = -1;
	sh_telnet->output_lock = false;

	k_work_cancel_delayable_sync(&sh_telnet->send_work,
				     &sh_telnet->work_sync);

	ret = net_socket_service_register(&telnet_server, sh_telnet->fds,
					  ARRAY_SIZE(sh_telnet->fds), NULL);
	if (ret < 0) {
		LOG_ERR("Failed to register socket service, %d", ret);
	}
}

static void telnet_command_send_reply(uint8_t *msg, uint16_t len)
{
	if (sh_telnet->fds[SOCK_ID_CLIENT].fd < 0) {
		return;
	}

	while (len > 0) {
		int ret;

		ret = zsock_send(sh_telnet->fds[SOCK_ID_CLIENT].fd, msg, len, 0);
		if (ret < 0) {
			LOG_ERR("Failed to send command %d, shutting down", ret);
			telnet_end_client_connection();
			break;
		}

		msg += ret;
		len -= ret;
	}
}

static void telnet_reply_ay_command(void)
{
	static const char alive[] = "Zephyr at your service\r\n";

	telnet_command_send_reply((uint8_t *)alive, strlen(alive));
}

static int telnet_echo_set(const struct shell *sh, bool val)
{
	int ret = shell_echo_set(sh_telnet->shell_context, val);

	if (ret < 0) {
		LOG_ERR("Failed to set echo to: %d, err: %d", val, ret);
	}
	return ret;
}

static void telnet_reply_dont_command(struct telnet_simple_command *cmd)
{
	switch (cmd->opt) {
	case NVT_OPT_ECHO:
	{
		int ret = telnet_echo_set(sh_telnet->shell_context, false);

		if (ret >= 0) {
			cmd->op = NVT_CMD_WILL_NOT;
		} else {
			cmd->op = NVT_CMD_WILL;
		}
		break;
	}
	default:
		cmd->op = NVT_CMD_WILL_NOT;
		break;
	}

	telnet_command_send_reply((uint8_t *)cmd,
				  sizeof(struct telnet_simple_command));
}

static void telnet_reply_do_command(struct telnet_simple_command *cmd)
{
	switch (cmd->opt) {
	case NVT_OPT_SUPR_GA:
		cmd->op = NVT_CMD_WILL;
		break;
	case NVT_OPT_ECHO:
	{
		int ret = telnet_echo_set(sh_telnet->shell_context, true);

		if (ret >= 0) {
			cmd->op = NVT_CMD_WILL;
		} else {
			cmd->op = NVT_CMD_WILL_NOT;
		}
		break;
	}
	default:
		cmd->op = NVT_CMD_WILL_NOT;
		break;
	}

	telnet_command_send_reply((uint8_t *)cmd,
				  sizeof(struct telnet_simple_command));
}

static void telnet_reply_command(struct telnet_simple_command *cmd)
{
	if (!cmd->iac) {
		return;
	}

	switch (cmd->op) {
	case NVT_CMD_AO:
		/* OK, no output then */
		sh_telnet->output_lock = true;
		sh_telnet->line_out.len = 0;
		k_work_cancel_delayable_sync(&sh_telnet->send_work,
					     &sh_telnet->work_sync);
		break;
	case NVT_CMD_AYT:
		telnet_reply_ay_command();
		break;
	case NVT_CMD_DO:
		telnet_reply_do_command(cmd);
		break;
	case NVT_CMD_DO_NOT:
		telnet_reply_dont_command(cmd);
		break;
	default:
		LOG_DBG("Operation %u not handled", cmd->op);
		break;
	}
}

static int telnet_send(bool block)
{
	int ret;
	uint8_t *msg = sh_telnet->line_out.buf;
	uint16_t len = sh_telnet->line_out.len;

	if (sh_telnet->line_out.len == 0) {
		return 0;
	}

	if (sh_telnet->fds[SOCK_ID_CLIENT].fd < 0) {
		return -ENOTCONN;
	}

	while (len > 0) {
		ret = zsock_send(sh_telnet->fds[SOCK_ID_CLIENT].fd, msg, len,
				 block ? 0 : ZSOCK_MSG_DONTWAIT);
		if (!block && (ret < 0) && (errno == EAGAIN)) {
			/* Not all data was sent - move the remaining data and
			 * update length.
			 */
			memmove(sh_telnet->line_out.buf, msg, len);
			sh_telnet->line_out.len = len;
			return -EAGAIN;
		}

		if (ret < 0) {
			ret = -errno;
			LOG_ERR("Failed to send %d, shutting down", -ret);
			telnet_end_client_connection();
			return ret;
		}

		msg += ret;
		len -= ret;
	}

	/* We reinitialize the line buffer */
	sh_telnet->line_out.len = 0;

	return 0;
}

static void telnet_send_prematurely(struct k_work *work)
{
	int ret;

	/* Use non-blocking send to prevent system workqueue blocking. */
	ret = telnet_send(false);
	if (ret == -EAGAIN) {
		/* Not all data was sent, reschedule the work. */
		k_work_reschedule(&sh_telnet->send_work, K_MSEC(TELNET_TIMEOUT));
	}
}

static int telnet_command_length(uint8_t op)
{
	if (op == NVT_CMD_SB || op == NVT_CMD_WILL || op == NVT_CMD_WILL_NOT ||
	    op == NVT_CMD_DO || op == NVT_CMD_DO_NOT) {
		return TELNET_WILL_DO_COMMAND_LEN;
	}

	return TELNET_MIN_COMMAND_LEN;
}

static inline int telnet_handle_command(struct telnet_simple_command *cmd)
{
	/* Commands are two or three bytes. */
	if (cmd->iac != NVT_CMD_IAC) {
		return 0;
	}

	if (IS_ENABLED(CONFIG_SHELL_TELNET_SUPPORT_COMMAND)) {
		LOG_DBG("Got a command %u/%u/%u", cmd->iac, cmd->op, cmd->opt);
		telnet_reply_command(cmd);
	}

	if (cmd->op == NVT_CMD_SB) {
		/* TODO Add subnegotiation support. */
		return -EOPNOTSUPP;
	}

	return 0;
}

static void telnet_recv(struct zsock_pollfd *pollfd)
{
	struct telnet_simple_command *cmd =
			(struct telnet_simple_command *)sh_telnet->cmd_buf;
	size_t len, off, buf_left, cmd_total_len;
	uint8_t *buf;
	int ret;

	k_mutex_lock(&sh_telnet->rx_lock, K_FOREVER);

	buf_left = sizeof(sh_telnet->rx_buf) - sh_telnet->rx_len;
	if (buf_left == 0) {
		/* No space left to read TCP stream, try again later. */
		k_mutex_unlock(&sh_telnet->rx_lock);
		k_msleep(10);
		return;
	}

	buf = sh_telnet->rx_buf + sh_telnet->rx_len;

	ret = zsock_recv(pollfd->fd, buf, buf_left, 0);
	if (ret < 0) {
		LOG_DBG("Telnet client error %d", ret);
		goto error;
	} else if (ret == 0) {
		LOG_DBG("Telnet client closed connection");
		goto error;
	}

	off = 0;
	len = ret;
	cmd_total_len = 0;
	/* Filter out and process commands from the data buffer. */
	while (off < len) {
		if (sh_telnet->cmd_len > 0) {
			/* Command mode */
			if (sh_telnet->cmd_len == 1) {
				/* Operation */
				cmd->op = *(buf + off);
				sh_telnet->cmd_len++;
				cmd_total_len++;
				off++;

				if (telnet_command_length(cmd->op) >
							TELNET_MIN_COMMAND_LEN) {
					continue;
				}
			} else if (sh_telnet->cmd_len == 2) {
				/* Option */
				cmd->opt = *(buf + off);
				sh_telnet->cmd_len++;
				cmd_total_len++;
				off++;
			}

			ret = telnet_handle_command(cmd);
			if (ret < 0) {
				goto error;
			} else {
				LOG_DBG("Handled command");
			}

			memset(cmd, 0, sizeof(*cmd));
			sh_telnet->cmd_len = 0;

			continue;
		}

		if (*(buf + off) == NVT_CMD_IAC) {
			cmd->iac = *(buf + off);
			sh_telnet->cmd_len++;
			cmd_total_len++;
			off++;
			continue;
		}

		/* Data byte, remove command bytes from the buffer, if any. */
		if (cmd_total_len > 0) {
			size_t data_off = off;

			off -= cmd_total_len;
			len -= cmd_total_len;
			cmd_total_len = 0;

			memmove(buf + off, buf + data_off, len);
		}

		off++;
	}

	if (cmd_total_len > 0) {
		/* In case the buffer ended with command, trim the buffer size
		 * here.
		 */
		len -=	cmd_total_len;
	}

	if (len == 0) {
		k_mutex_unlock(&sh_telnet->rx_lock);
		return;
	}

	sh_telnet->rx_len += len;

	k_mutex_unlock(&sh_telnet->rx_lock);

	sh_telnet->shell_handler(SHELL_TRANSPORT_EVT_RX_RDY,
				 sh_telnet->shell_context);

	return;

error:
	k_mutex_unlock(&sh_telnet->rx_lock);
	telnet_end_client_connection();
}

static void telnet_restart_server(void)
{
	int ret;

	if (sh_telnet->fds[SOCK_ID_IPV4_LISTEN].fd >= 0) {
		(void)zsock_close(sh_telnet->fds[SOCK_ID_IPV4_LISTEN].fd);
		sh_telnet->fds[SOCK_ID_IPV4_LISTEN].fd = -1;
	}

	if (sh_telnet->fds[SOCK_ID_IPV6_LISTEN].fd >= 0) {
		(void)zsock_close(sh_telnet->fds[SOCK_ID_IPV6_LISTEN].fd);
		sh_telnet->fds[SOCK_ID_IPV6_LISTEN].fd = -1;
	}

	if (sh_telnet->fds[SOCK_ID_CLIENT].fd >= 0) {
		(void)zsock_close(sh_telnet->fds[SOCK_ID_CLIENT].fd);
		sh_telnet->fds[SOCK_ID_CLIENT].fd = -1;
	}

	ret = telnet_init(sh_telnet);
	if (ret < 0) {
		LOG_ERR("Telnet fatal error, failed to restart server (%d)", ret);
		(void)net_socket_service_unregister(&telnet_server);
	}
}

static void telnet_accept(struct zsock_pollfd *pollfd)
{
	int sock, ret = 0;
	struct sockaddr addr;
	socklen_t addrlen = sizeof(struct sockaddr);

	sock = zsock_accept(pollfd->fd, &addr, &addrlen);
	if (sock < 0) {
		ret = -errno;
		NET_ERR("Telnet accept error (%d)", ret);
		return;
	}

	if (sh_telnet->fds[SOCK_ID_CLIENT].fd > 0) {
		/* Too many connections. */
		ret = 0;
		NET_ERR("Telnet client already connected.");
		goto error;
	}

	sh_telnet->fds[SOCK_ID_CLIENT].fd = sock;
	sh_telnet->fds[SOCK_ID_CLIENT].events = ZSOCK_POLLIN;
	sh_telnet->rx_len = 0;
	sh_telnet->cmd_len = 0;
	sh_telnet->line_out.len = 0;

	ret = net_socket_service_register(&telnet_server, sh_telnet->fds,
					  ARRAY_SIZE(sh_telnet->fds), NULL);
	if (ret < 0) {
		LOG_ERR("Failed to register socket service, (%d)", ret);
		sh_telnet->fds[SOCK_ID_CLIENT].fd = -1;
		goto error;
	}

	LOG_DBG("Telnet client connected (family AF_INET%s)",
		addr.sa_family == AF_INET ? "" : "6");

	/* Disable echo - if command handling is enabled we reply that we
	 * support echo.
	 */
	(void)telnet_echo_set(sh_telnet->shell_context, false);

	return;

error:
	if (sock > 0) {
		(void)zsock_close(sock);
	}

	if (ret < 0) {
		telnet_restart_server();
	}
}

static void telnet_server_cb(struct k_work *work)
{
	struct net_socket_service_event *evt =
		CONTAINER_OF(work, struct net_socket_service_event, work);
	int sock_error;
	socklen_t optlen = sizeof(int);

	if (sh_telnet == NULL) {
		return;
	}

	if ((evt->event.revents & ZSOCK_POLLERR) ||
	    (evt->event.revents & ZSOCK_POLLNVAL)) {
		(void)zsock_getsockopt(evt->event.fd, SOL_SOCKET,
				       SO_ERROR, &sock_error, &optlen);
		NET_ERR("Telnet socket %d error (%d)", evt->event.fd, sock_error);

		if (evt->event.fd == sh_telnet->fds[SOCK_ID_CLIENT].fd) {
			return telnet_end_client_connection();
		}

		goto error;
	}

	if (!(evt->event.revents & ZSOCK_POLLIN)) {
		return;
	}

	if (evt->event.fd == sh_telnet->fds[SOCK_ID_IPV4_LISTEN].fd) {
		return telnet_accept(&sh_telnet->fds[SOCK_ID_IPV4_LISTEN]);
	} else if (evt->event.fd == sh_telnet->fds[SOCK_ID_IPV6_LISTEN].fd) {
		return telnet_accept(&sh_telnet->fds[SOCK_ID_IPV6_LISTEN]);
	} else if (evt->event.fd == sh_telnet->fds[SOCK_ID_CLIENT].fd) {
		return telnet_recv(&sh_telnet->fds[SOCK_ID_CLIENT]);
	}

	NET_ERR("Unexpected FD received for telnet, restarting service.");

error:
	telnet_restart_server();
}

static int telnet_setup_server(struct zsock_pollfd *pollfd, sa_family_t family,
			       struct sockaddr *addr, socklen_t addrlen)
{
	int ret = 0;

	pollfd->fd = zsock_socket(family, SOCK_STREAM, IPPROTO_TCP);
	if (pollfd->fd < 0) {
		ret = -errno;
		LOG_ERR("Failed to create telnet AF_INET%s socket",
			family == AF_INET ? "" : "6");
		goto error;
	}

	if (zsock_bind(pollfd->fd, addr, addrlen) < 0) {
		ret = -errno;
		LOG_ERR("Cannot bind on family AF_INET%s (%d)",
			family == AF_INET ? "" : "6", ret);
		goto error;
	}

	if (zsock_listen(pollfd->fd, 1)) {
		ret = -errno;
		LOG_ERR("Cannot listen on family AF_INET%s (%d)",
			family == AF_INET ? "" : "6", ret);
		goto error;
	}

	pollfd->events = ZSOCK_POLLIN;

	LOG_DBG("Telnet console enabled on AF_INET%s",
		family == AF_INET ? "" : "6");

	return 0;

error:
	LOG_ERR("Unable to start telnet on AF_INET%s (%d)",
		family == AF_INET ? "" : "6", ret);

	if (pollfd->fd >= 0) {
		(void)zsock_close(pollfd->fd);
		pollfd->fd = -1;
	}

	return ret;
}

static int telnet_init(struct shell_telnet *ctx)
{
	int ret;

	if (IS_ENABLED(CONFIG_NET_IPV4)) {
		struct sockaddr_in any_addr4 = {
			.sin_family = AF_INET,
			.sin_port = htons(TELNET_PORT),
			.sin_addr = INADDR_ANY_INIT
		};

		ret = telnet_setup_server(&ctx->fds[SOCK_ID_IPV4_LISTEN],
					  AF_INET, (struct sockaddr *)&any_addr4,
					  sizeof(any_addr4));
		if (ret < 0) {
			goto error;
		}
	}

	if (IS_ENABLED(CONFIG_NET_IPV6)) {
		struct sockaddr_in6 any_addr6 = {
			.sin6_family = AF_INET6,
			.sin6_port = htons(TELNET_PORT),
			.sin6_addr = IN6ADDR_ANY_INIT
		};

		ret = telnet_setup_server(&ctx->fds[SOCK_ID_IPV6_LISTEN],
					  AF_INET6, (struct sockaddr *)&any_addr6,
					  sizeof(any_addr6));
		if (ret < 0) {
			goto error;
		}
	}

	ret = net_socket_service_register(&telnet_server, ctx->fds,
					  ARRAY_SIZE(ctx->fds), NULL);
	if (ret < 0) {
		LOG_ERR("Failed to register socket service, %d", ret);
		goto error;
	}

	LOG_INF("Telnet shell backend initialized");

	return 0;

error:
	if (ctx->fds[SOCK_ID_IPV4_LISTEN].fd >= 0) {
		(void)zsock_close(ctx->fds[SOCK_ID_IPV4_LISTEN].fd);
		ctx->fds[SOCK_ID_IPV4_LISTEN].fd = -1;
	}

	if (ctx->fds[SOCK_ID_IPV6_LISTEN].fd >= 0) {
		(void)zsock_close(ctx->fds[SOCK_ID_IPV6_LISTEN].fd);
		ctx->fds[SOCK_ID_IPV6_LISTEN].fd = -1;
	}

	return ret;
}

/* Shell API */

static int init(const struct shell_transport *transport,
		const void *config,
		shell_transport_handler_t evt_handler,
		void *context)
{
	int err;

	sh_telnet = (struct shell_telnet *)transport->ctx;

	memset(sh_telnet, 0, sizeof(struct shell_telnet));
	for (int i = 0; i < ARRAY_SIZE(sh_telnet->fds); i++) {
		sh_telnet->fds[i].fd = -1;
	}

	sh_telnet->shell_handler = evt_handler;
	sh_telnet->shell_context = context;

	err = telnet_init(sh_telnet);
	if (err != 0) {
		return err;
	}

	k_work_init_delayable(&sh_telnet->send_work, telnet_send_prematurely);
	k_mutex_init(&sh_telnet->rx_lock);

	return 0;
}

static int uninit(const struct shell_transport *transport)
{
	if (sh_telnet == NULL) {
		return -ENODEV;
	}

	return 0;
}

static int enable(const struct shell_transport *transport, bool blocking)
{
	if (sh_telnet == NULL) {
		return -ENODEV;
	}

	return 0;
}

static int write(const struct shell_transport *transport,
		 const void *data, size_t length, size_t *cnt)
{
	struct shell_telnet_line_buf *lb;
	size_t copy_len;
	int err;
	uint32_t timeout;
	bool was_running;

	if (sh_telnet == NULL) {
		*cnt = 0;
		return -ENODEV;
	}

	if (sh_telnet->fds[SOCK_ID_CLIENT].fd < 0 || sh_telnet->output_lock) {
		*cnt = length;
		return 0;
	}

	*cnt = 0;
	lb = &sh_telnet->line_out;

	/* Stop the transmission timer, so it does not interrupt the operation.
	 */
	timeout = k_ticks_to_ms_ceil32(
			k_work_delayable_remaining_get(&sh_telnet->send_work));
	was_running = k_work_cancel_delayable_sync(&sh_telnet->send_work,
						   &sh_telnet->work_sync);

	do {
		if (lb->len + length - *cnt > TELNET_LINE_SIZE) {
			copy_len = TELNET_LINE_SIZE - lb->len;
		} else {
			copy_len = length - *cnt;
		}

		memcpy(lb->buf + lb->len, (uint8_t *)data + *cnt, copy_len);
		lb->len += copy_len;

		/* Send the data immediately if the buffer is full or line feed
		 * is recognized.
		 */
		if (lb->buf[lb->len - 1] == '\n' ||
		    lb->len == TELNET_LINE_SIZE) {
			err = telnet_send(true);
			if (err != 0) {
				*cnt = length;
				return err;
			}
		}

		*cnt += copy_len;
	} while (*cnt < length);

	if (lb->len > 0) {
		/* Check if the timer was already running, initialize otherwise.
		 */
		timeout = was_running ? timeout : TELNET_TIMEOUT;

		k_work_reschedule(&sh_telnet->send_work, K_MSEC(timeout));
	}

	sh_telnet->shell_handler(SHELL_TRANSPORT_EVT_TX_RDY,
				 sh_telnet->shell_context);

	return 0;
}

static int read(const struct shell_transport *transport,
		void *data, size_t length, size_t *cnt)
{
	size_t read_len;

	if (sh_telnet == NULL) {
		return -ENODEV;
	}

	if (sh_telnet->fds[SOCK_ID_CLIENT].fd < 0) {
		goto no_data;
	}

	k_mutex_lock(&sh_telnet->rx_lock, K_FOREVER);

	if (sh_telnet->rx_len == 0) {
		k_mutex_unlock(&sh_telnet->rx_lock);
		goto no_data;
	}

	read_len = sh_telnet->rx_len;
	if (read_len > length) {
		read_len = length;
	}

	memcpy(data, sh_telnet->rx_buf, read_len);
	*cnt = read_len;

	sh_telnet->rx_len -= read_len;
	if (sh_telnet->rx_len > 0) {
		memmove(sh_telnet->rx_buf, sh_telnet->rx_buf + read_len,
			sh_telnet->rx_len);
	}

	k_mutex_unlock(&sh_telnet->rx_lock);

	return 0;

no_data:
	*cnt = 0;
	return 0;
}

const struct shell_transport_api shell_telnet_transport_api = {
	.init = init,
	.uninit = uninit,
	.enable = enable,
	.write = write,
	.read = read
};

static int enable_shell_telnet(void)
{
	bool log_backend = CONFIG_SHELL_TELNET_INIT_LOG_LEVEL > 0;
	uint32_t level = (CONFIG_SHELL_TELNET_INIT_LOG_LEVEL > LOG_LEVEL_DBG) ?
		      CONFIG_LOG_MAX_LEVEL : CONFIG_SHELL_TELNET_INIT_LOG_LEVEL;
	static const struct shell_backend_config_flags cfg_flags =
					SHELL_DEFAULT_BACKEND_CONFIG_FLAGS;

	return shell_init(&shell_telnet, NULL, cfg_flags, log_backend, level);
}

BUILD_ASSERT(CONFIG_SHELL_TELNET_INIT_PRIORITY > CONFIG_NET_SOCKETS_SERVICE_INIT_PRIO,
	     "CONFIG_SHELL_TELNET_INIT_PRIORITY must be higher than "
	     "CONFIG_NET_SOCKETS_SERVICE_INIT_PRIO");

SYS_INIT(enable_shell_telnet, APPLICATION, CONFIG_SHELL_TELNET_INIT_PRIORITY);

const struct shell *shell_backend_telnet_get_ptr(void)
{
	return &shell_telnet;
}
