/*
 * 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 LOG_LEVEL CONFIG_TELNET_CONSOLE_LOG_LEVEL
#define LOG_DOMAIN net_telnet
#include <logging/log.h>
LOG_MODULE_REGISTER(LOG_DOMAIN);

#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 = 0U;
	telnet_rb.line_out = 0U;

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

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 = 0U;
	}

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

	/* 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 = 0U;
		}
	}

	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 = 0U;
	}

	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)
{
	unsigned 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();
		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 = 0U;

		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:
		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;

	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,
			union net_ip_header *ip_hdr,
			union net_proto_header *proto_hdr,
			int status,
			void *user_data)
{
	if (!pkt || status) {
		telnet_end_client_connection();

		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) {
		LOG_ERR("Error %d", error);
		goto error;
	}

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

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

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

	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)) {
		LOG_ERR("No context available");
		goto error;
	}

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

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

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

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

	return;
error:
	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));

	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);
