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

/**
 * @file
 * @brief Telnet console
 *
 *
 * Telnet console driver.
 * Hooks into the printk and fputc (for printf) modules.
 *
 * Telnet has been standardized in 1983
 * RFC 854 - https://tools.ietf.org/html/rfc854
 */

#define SYS_LOG_LEVEL CONFIG_SYS_LOG_TELNET_CONSOLE_LEVEL
#define SYS_LOG_DOMAIN "net/telnet"
#include <logging/sys_log.h>

#include <zephyr.h>
#include <init.h>
#include <misc/printk.h>

#include <console/console.h>
#include <net/buf.h>
#include <net/net_pkt.h>
#include <net/net_ip.h>
#include <net/net_context.h>

#include "telnet_protocol.h"

/* Various definitions mapping the telnet service configuration options */
#define TELNET_PORT		CONFIG_TELNET_CONSOLE_PORT
#define TELNET_STACK_SIZE	CONFIG_TELNET_CONSOLE_THREAD_STACK
#define TELNET_PRIORITY		CONFIG_TELNET_CONSOLE_PRIO
#define TELNET_LINES		CONFIG_TELNET_CONSOLE_LINE_BUF_NUMBERS
#define TELNET_LINE_SIZE	CONFIG_TELNET_CONSOLE_LINE_BUF_SIZE
#define TELNET_TIMEOUT		K_MSEC(CONFIG_TELNET_CONSOLE_SEND_TIMEOUT)
#define TELNET_THRESHOLD	CONFIG_TELNET_CONSOLE_SEND_THRESHOLD

#define TELNET_MIN_MSG		2

/* These 2 structures below are used to store the console output
 * before sending it to the client. This is done to keep some
 * reactivity: the ring buffer is non-protected, if first line has
 * not been sent yet, and if next line is reaching the same index in rb,
 * the first one will be replaced. In a perfect world, this should
 * not happen. However on a loaded system with a lot of debug output
 * this is bound to happen eventualy, moreover if it does not have
 * the luxury to bufferize as much as it wants to. Just raise
 * CONFIG_TELNET_CONSOLE_LINE_BUF_NUMBERS if possible.
 */
struct line_buf {
	char buf[TELNET_LINE_SIZE];
	u16_t len;
};

struct line_buf_rb {
	struct line_buf l_bufs[TELNET_LINES];
	u16_t line_in;
	u16_t line_out;
};

static struct line_buf_rb telnet_rb;

static K_THREAD_STACK_DEFINE(telnet_stack, TELNET_STACK_SIZE);
static struct k_thread telnet_thread_data;
static K_SEM_DEFINE(send_lock, 0, UINT_MAX);

/* The timer is used to send non-lf terminated output that has
 * been around for "tool long". This will prove to be useful
 * to send the shell prompt for instance.
 * ToDo: raise the time, incrementaly, when no output is coming
 *       so the timer will kick in less and less.
 */
static void telnet_send_prematurely(struct k_timer *timer);
static K_TIMER_DEFINE(send_timer, telnet_send_prematurely, NULL);

/* For now we handle a unique telnet client connection */
static struct net_context *client_cnx;
static struct net_pkt *out_pkt;
static int (*orig_printk_hook)(int);

static struct k_fifo *avail_queue;
static struct k_fifo *input_queue;

#ifdef CONFIG_TELNET_CONSOLE_SUPPORT_COMMAND
static K_SEM_DEFINE(cmd_lock, 1, 1);
static struct telnet_simple_command telnet_cmd;
#endif /* CONFIG_TELNET_CONSOLE_SUPPORT_COMMAND */

extern void __printk_hook_install(int (*fn)(int));
extern void *__printk_get_hook(void);

static void telnet_rb_init(void)
{
	int i;

	telnet_rb.line_in = 0;
	telnet_rb.line_out = 0;

	for (i = 0; i < TELNET_LINES; i++) {
		telnet_rb.l_bufs[i].len = 0;
	}
}

static void telnet_end_client_connection(void)
{
	__printk_hook_install(orig_printk_hook);
	orig_printk_hook = NULL;

	k_timer_stop(&send_timer);

	net_context_put(client_cnx);
	client_cnx = NULL;

	if (out_pkt) {
		net_pkt_unref(out_pkt);
	}

	telnet_rb_init();
}

static int telnet_setup_out_pkt(struct net_context *client)
{
	out_pkt = net_pkt_get_tx(client, K_FOREVER);
	if (!out_pkt) {
		/* Cannot happen atm, net_pkt waits indefinitely */
		return -ENOBUFS;
	}

	return 0;
}

static void telnet_rb_switch(void)
{
	telnet_rb.line_in++;

	if (telnet_rb.line_in == TELNET_LINES) {
		telnet_rb.line_in = 0;
	}

	telnet_rb.l_bufs[telnet_rb.line_in].len = 0;

	/* Unfortunately, we don't have enough line buffer,
	 * so we eat the next to be sent.
	 */
	if (telnet_rb.line_in == telnet_rb.line_out) {
		telnet_rb.line_out++;
		if (telnet_rb.line_out == TELNET_LINES) {
			telnet_rb.line_out = 0;
		}
	}

	k_timer_start(&send_timer, TELNET_TIMEOUT, TELNET_TIMEOUT);
	k_sem_give(&send_lock);
}

static inline struct line_buf *telnet_rb_get_line_out(void)
{
	u16_t out = telnet_rb.line_out;

	telnet_rb.line_out++;
	if (telnet_rb.line_out == TELNET_LINES) {
		telnet_rb.line_out = 0;
	}

	if (!telnet_rb.l_bufs[out].len) {
		return NULL;
	}

	return &telnet_rb.l_bufs[out];
}

static inline struct line_buf *telnet_rb_get_line_in(void)
{
	return &telnet_rb.l_bufs[telnet_rb.line_in];
}

/* The actual printk hook */
static int telnet_console_out(int c)
{
	int key = irq_lock();
	struct line_buf *lb = telnet_rb_get_line_in();
	bool yield = false;

	lb->buf[lb->len++] = (char)c;

	if (c == '\n' || lb->len == TELNET_LINE_SIZE - 1) {
		lb->buf[lb->len-1] = NVT_CR;
		lb->buf[lb->len++] = NVT_LF;
		telnet_rb_switch();
		yield = true;
	}

	irq_unlock(key);

#ifdef CONFIG_TELNET_CONSOLE_DEBUG_DEEP
	/* This is ugly, but if one wants to debug telnet, it
	 * will also output the character to original console
	 */
	orig_printk_hook(c);
#endif

	if (yield) {
		k_yield();
	}

	return c;
}

static void telnet_send_prematurely(struct k_timer *timer)
{
	struct line_buf *lb = telnet_rb_get_line_in();

	if (lb->len >= TELNET_THRESHOLD) {
		telnet_rb_switch();
	}
}

static void telnet_sent_cb(struct net_context *client,
			   int status, void *token, void *user_data)
{
	if (status) {
		telnet_end_client_connection();
		SYS_LOG_ERR("Could not sent last packet");
	}
}

static inline bool telnet_send(void)
{
	struct line_buf *lb = telnet_rb_get_line_out();

	if (lb) {
		net_pkt_append_all(out_pkt, lb->len, (u8_t *)lb->buf,
				   K_FOREVER);

		/* We reinitialize the line buffer */
		lb->len = 0;

		if (net_context_send(out_pkt, telnet_sent_cb,
				     K_NO_WAIT, NULL, NULL) ||
		    telnet_setup_out_pkt(client_cnx)) {
			return false;
		}
	}

	return true;
}

#ifdef CONFIG_TELNET_CONSOLE_SUPPORT_COMMAND

static int telnet_console_out_nothing(int c)
{
	return c;
}

static inline void telnet_command_send_reply(u8_t *msg, u16_t len)
{
	net_pkt_append_all(out_pkt, len, msg, K_FOREVER);

	net_context_send(out_pkt, telnet_sent_cb,
			 K_NO_WAIT, NULL, NULL);

	telnet_setup_out_pkt(client_cnx);
}

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

	telnet_command_send_reply((u8_t *)alive, 24);
}

static inline void telnet_reply_do_command(void)
{
	switch (telnet_cmd.opt) {
	case NVT_OPT_SUPR_GA:
		telnet_cmd.op = NVT_CMD_WILL;
		break;
	default:
		telnet_cmd.op = NVT_CMD_WONT;
		break;
	}

	telnet_command_send_reply((u8_t *)&telnet_cmd,
				  sizeof(struct telnet_simple_command));
}

static inline void telnet_reply_command(void)
{
	if (k_sem_take(&cmd_lock, K_NO_WAIT)) {
		return;
	}

	if (!telnet_cmd.iac) {
		goto out;
	}

	switch (telnet_cmd.op) {
	case NVT_CMD_AO:
		/* OK, no output then */
		__printk_hook_install(telnet_console_out_nothing);
		telnet_rb_init();
		break;
	case NVT_CMD_AYT:
		telnet_reply_ay_command();
		break;
	case NVT_CMD_DO:
		telnet_reply_do_command();
		break;
	default:
		SYS_LOG_DBG("Operation %u not handled",
			    telnet_cmd.op);
		break;
	}

	telnet_cmd.iac = NVT_NUL;
	telnet_cmd.op  = NVT_NUL;
	telnet_cmd.opt = NVT_NUL;
out:
	k_sem_give(&cmd_lock);
}
#else
#define telnet_reply_command()
#endif /* CONFIG_TELNET_CONSOLE_SUPPORT_COMMAND */

static inline bool telnet_handle_command(struct net_pkt *pkt)
{
	struct telnet_simple_command *cmd =
		(struct telnet_simple_command *)net_pkt_appdata(pkt);

	if (cmd->iac != NVT_CMD_IAC) {
		return false;
	}

#ifdef CONFIG_TELNET_CONSOLE_SUPPORT_COMMAND
	cmd = (struct telnet_simple_command *)l_start;

	SYS_LOG_DBG("Got a command %u/%u/%u", cmd->iac, cmd->op, cmd->opt);

	if (!k_sem_take(&cmd_lock, K_NO_WAIT)) {
		telnet_command_cpy(&telnet_cmd, cmd);

		k_sem_give(&cmd_lock);
		k_sem_give(&send_lock);
	}
#endif /* CONFIG_TELNET_CONSOLE_SUPPORT_COMMAND */

	return true;
}

static inline void telnet_handle_input(struct net_pkt *pkt)
{
	struct console_input *input;
	u16_t len, offset, pos;

	len = net_pkt_appdatalen(pkt);
	if (len > CONSOLE_MAX_LINE_LEN || len < TELNET_MIN_MSG) {
		return;
	}

	if (telnet_handle_command(pkt)) {
		return;
	}

	if (!avail_queue || !input_queue) {
		return;
	}

	input = k_fifo_get(avail_queue, K_NO_WAIT);
	if (!input) {
		return;
	}

	offset = net_pkt_get_len(pkt) - len;
	net_frag_read(pkt->frags, offset, &pos, len, (u8_t *)input->line);

	/* LF/CR will be removed if only the line is not NUL terminated */
	if (input->line[len-1] != NVT_NUL) {
		if (input->line[len-1] == NVT_LF) {
			input->line[len-1] = NVT_NUL;
		}

		if (input->line[len-2] == NVT_CR) {
			input->line[len-2] = NVT_NUL;
		}
	}

	k_fifo_put(input_queue, input);
}

static void telnet_recv(struct net_context *client,
			struct net_pkt *pkt,
			int status,
			void *user_data)
{
	if (!pkt || status) {
		telnet_end_client_connection();

		SYS_LOG_DBG("Telnet client dropped (AF_INET%s) status %d",
			    net_context_get_family(client) == AF_INET ?
			    "" : "6", status);
		return;
	}

	telnet_handle_input(pkt);

	net_pkt_unref(pkt);
}

/* Telnet server loop, used to send buffered output in the RB */
static void telnet_run(void)
{
	while (true) {
		k_sem_take(&send_lock, K_FOREVER);

		if (!telnet_send()) {
			telnet_end_client_connection();
		}

		telnet_reply_command();
	}
}

static void telnet_accept(struct net_context *client,
			  struct sockaddr *addr,
			  socklen_t addrlen,
			  int error,
			  void *user_data)
{
	if (error) {
		SYS_LOG_ERR("Error %d", error);
		goto error;
	}

	if (client_cnx) {
		SYS_LOG_WRN("A telnet client is already in.");
		goto error;
	}

	if (net_context_recv(client, telnet_recv, 0, NULL)) {
		SYS_LOG_ERR("Unable to setup reception (family %u)",
			    net_context_get_family(client));
		goto error;
	}

	if (telnet_setup_out_pkt(client)) {
		goto error;
	}

	SYS_LOG_DBG("Telnet client connected (family AF_INET%s)",
		    net_context_get_family(client) == AF_INET ? "" : "6");

	orig_printk_hook = __printk_get_hook();
	__printk_hook_install(telnet_console_out);

	client_cnx = client;
	k_timer_start(&send_timer, TELNET_TIMEOUT, TELNET_TIMEOUT);

	return;
error:
	net_context_put(client);
}

static void telnet_setup_server(struct net_context **ctx, sa_family_t family,
				struct sockaddr *addr, socklen_t addrlen)
{
	if (net_context_get(family, SOCK_STREAM, IPPROTO_TCP, ctx)) {
		SYS_LOG_ERR("No context available");
		goto error;
	}

	if (net_context_bind(*ctx, addr, addrlen)) {
		SYS_LOG_ERR("Cannot bind on family AF_INET%s",
			    family == AF_INET ? "" : "6");
		goto error;
	}

	if (net_context_listen(*ctx, 0)) {
		SYS_LOG_ERR("Cannot listen on");
		goto error;
	}

	if (net_context_accept(*ctx, telnet_accept, K_NO_WAIT, NULL)) {
		SYS_LOG_ERR("Cannot accept");
		goto error;
	}

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

	return;
error:
	SYS_LOG_ERR("Unable to start telnet on AF_INET%s",
		    family == AF_INET ? "" : "6");

	if (*ctx) {
		net_context_put(*ctx);
		*ctx = NULL;
	}
}

void telnet_register_input(struct k_fifo *avail, struct k_fifo *lines,
			   u8_t (*completion)(char *str, u8_t len))
{
	ARG_UNUSED(completion);

	avail_queue = avail;
	input_queue = lines;
}

static int telnet_console_init(struct device *arg)
{
#ifdef CONFIG_NET_IPV4
	struct sockaddr_in any_addr4 = {
		.sin_family = AF_INET,
		.sin_port = htons(TELNET_PORT),
		.sin_addr = INADDR_ANY_INIT
	};
	static struct net_context *ctx4;
#endif
#ifdef CONFIG_NET_IPV6
	struct sockaddr_in6 any_addr6 = {
		.sin6_family = AF_INET6,
		.sin6_port = htons(TELNET_PORT),
		.sin6_addr = IN6ADDR_ANY_INIT
	};
	static struct net_context *ctx6;
#endif

#ifdef CONFIG_NET_IPV4
	telnet_setup_server(&ctx4, AF_INET,
			    (struct sockaddr *)&any_addr4,
			    sizeof(any_addr4));
#endif
#ifdef CONFIG_NET_IPV6
	telnet_setup_server(&ctx6, AF_INET6,
			    (struct sockaddr *)&any_addr6,
			    sizeof(any_addr6));
#endif

	k_thread_create(&telnet_thread_data, telnet_stack,
			TELNET_STACK_SIZE,
			(k_thread_entry_t)telnet_run,
			NULL, NULL, NULL,
			K_PRIO_COOP(TELNET_PRIORITY), 0, K_MSEC(10));

	SYS_LOG_INF("Telnet console initialized");

	return 0;
}

/* Telnet is initialized as an application directly, as it requires
 * the whole network stack to be ready.
 */
SYS_INIT(telnet_console_init, APPLICATION, CONFIG_TELNET_CONSOLE_INIT_PRIORITY);
