/*
 * Copyright (c) 2018 Oticon A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <ctype.h>
#include <zephyr/init.h>
#include <zephyr/kernel.h>
#include <zephyr/console/console.h>
#include "posix_board_if.h"
#include <string.h>
#include <sys/time.h>
#include <sys/select.h>
#include <unistd.h>

#define DEBUG_ECHO 0

#if (DEBUG_ECHO)
#define ECHO(...) printf(__VA_ARGS__)
#else
#define ECHO(...)
#endif

#if defined(CONFIG_NATIVE_POSIX_STDOUT_CONSOLE)
/**
 *
 * @brief Initialize the driver that provides the printk output
 *
 */
static void native_posix_stdout_init(void)
{
#ifdef CONFIG_PRINTK
	extern void __printk_hook_install(int (*fn)(int));
	__printk_hook_install(putchar);
#endif
}

/**
 * Ensure that whatever was written thru printk is displayed now
 */
void posix_flush_stdout(void)
{
	fflush(stdout);
}
#endif /* CONFIG_NATIVE_POSIX_STDOUT_CONSOLE */

#if defined(CONFIG_NATIVE_POSIX_STDIN_CONSOLE)

#define VALID_DIRECTIVES \
	"Valid native console driver directives:\n" \
	"  !wait %%u\n" \
	"  !quit\n"

static struct k_fifo *avail_queue;
static struct k_fifo *lines_queue;
static uint8_t (*completion_cb)(char *line, uint8_t len);
static bool stdin_is_tty;

static K_KERNEL_STACK_DEFINE(stack, CONFIG_ARCH_POSIX_RECOMMENDED_STACK_SIZE);
static struct k_thread native_stdio_thread;

static inline void found_eof(void)
{
	/*
	 * Once stdin is closed or the input file has ended,
	 * there is no need to try again
	 */
	ECHO("Got EOF\n");
	k_thread_abort(&native_stdio_thread);
}

/*
 * Check if the command is a directive the driver handles on its own
 * and if it is, handle it.
 * If not return 0 (so it can be passed to the shell)
 *
 * Inputs
 *   s       Command string
 *   towait  Pointer to the amount of time wait until attempting to receive
 *           the next command
 *
 * return 0 if it is not a directive
 * return > 0 if it was a directive (command starts with '!')
 * return 2 if the driver directive requires to pause processing input
 */
static int catch_directive(char *s, int32_t *towait)
{
	while (*s != 0  && isspace(*s) != 0) {
		s++;
	}

	if (*s != '!') {
		return 0;
	}

	if (strncmp(s, "!wait", 5) == 0) {
		int ret;

		ret = sscanf(&s[5], "%i", towait);
		if (ret != 1) {
			posix_print_error_and_exit("%s(): '%s' not understood, "
						   "!wait syntax: !wait %%i\n",
						   __func__, s);
		}
		return 2;
	} else if (strcmp(s, "!quit") == 0) {
		posix_exit(0);
	}

	posix_print_warning("%s(): '%s' not understood\n" VALID_DIRECTIVES,
			    __func__, s);

	return 1;
}

/**
 * Check if there is data ready in stdin
 */
static int stdin_not_ready(void)
{
	int ready;
	fd_set readfds;
	struct timeval timeout;

	timeout.tv_usec = 0;
	timeout.tv_sec  = 0;

	FD_ZERO(&readfds);
	FD_SET(STDIN_FILENO, &readfds);

	ready = select(STDIN_FILENO+1, &readfds, NULL, NULL, &timeout);

	if (ready == 0) {
		return 1;
	} else if (ready == -1) {
		posix_print_error_and_exit("%s: Error on select ()\n",
					   __func__);
	}

	return 0;
}

/**
 * Check if there is any line in the stdin buffer,
 * if there is and we have available shell buffers feed it to the shell
 *
 * This function returns how long the thread should wait in ms,
 * before checking again the stdin buffer
 */
static int32_t attempt_read_from_stdin(void)
{
	static struct console_input *cmd;
	int32_t towait = CONFIG_NATIVE_STDIN_POLL_PERIOD;

	while (1) {
		char *ret;
		int last;
		int is_directive;

		if (feof(stdin)) {
			found_eof();
		}

		/*
		 * If stdin comes from a terminal, we check if the user has
		 * input something, and if not we pause the process.
		 *
		 * If stdin is not coming from a terminal, but from a file or
		 * pipe, we always proceed to try to get data and block until
		 * we do
		 */
		if (stdin_is_tty && stdin_not_ready()) {
			return towait;
		}

		/* Pick next available shell line buffer */
		if (!cmd) {
			cmd = k_fifo_get(avail_queue, K_NO_WAIT);
			if (!cmd) {
				return towait;
			}
		}

		/*
		 * By default stdin is (_IOLBF) line buffered when connected to
		 * a terminal and fully buffered (_IOFBF) when connected to a
		 * pipe/file.
		 * If we got a terminal: we already checked for it to be ready
		 * and therefore a full line should be there for us.
		 *
		 * If we got a pipe or file we will block until we get a line,
		 * or we reach EOF
		 */
		ret = fgets(cmd->line, CONSOLE_MAX_LINE_LEN, stdin);
		if (ret == NULL) {
			if (feof(stdin)) {
				found_eof();
			}
			/*
			 * Otherwise this was an unexpected error we do
			 * not try to handle
			 */
			return towait;
		}

		/* Remove a possible end of line and other trailing spaces */
		last = (int)strlen(cmd->line) - 1;
		while ((last >= 0) && isspace(cmd->line[last]) != 0) {
			cmd->line[last--] = 0;
		}

		ECHO("Got: \"%s\"\n", cmd->line);

		/*
		 * This console has a special set of directives which start with
		 * "!" which we capture here
		 */
		is_directive = catch_directive(cmd->line, &towait);
		if (is_directive == 2) {
			return towait;
		} else if (is_directive > 0) {
			continue;
		}

		/* Let's give it to the shell to handle */
		k_fifo_put(lines_queue, cmd);
		cmd = NULL;
	}

	return towait;
}

/**
 * This thread will check if there is any new line in the stdin buffer
 * every CONFIG_NATIVE_STDIN_POLL_PERIOD ms
 *
 * If there is, it will feed it to the shell
 */
static void native_stdio_runner(void *p1, void *p2, void *p3)
{
	stdin_is_tty = isatty(STDIN_FILENO);

	while (1) {
		int32_t wait_time = attempt_read_from_stdin();

		k_sleep(wait_time);
	}
}
#endif /* CONFIG_NATIVE_POSIX_STDIN_CONSOLE */

static int native_posix_console_init(void)
{

#if defined(CONFIG_NATIVE_POSIX_STDOUT_CONSOLE)
	native_posix_stdout_init();
#endif

	return 0;
}

SYS_INIT(native_posix_console_init, PRE_KERNEL_1,
	CONFIG_NATIVE_POSIX_CONSOLE_INIT_PRIORITY);
