/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ctype.h>
#include "shell_ops.h"

#define CMD_CURSOR_LEN 8
void z_shell_op_cursor_vert_move(const struct shell *sh, int32_t delta)
{
	char dir = delta > 0 ? 'A' : 'B';

	if (delta == 0) {
		return;
	}

	if (delta < 0) {
		delta = -delta;
	}

	Z_SHELL_VT100_CMD(sh, "\e[%d%c", delta, dir);
}

void z_shell_op_cursor_horiz_move(const struct shell *sh, int32_t delta)
{
	char dir = delta > 0 ? 'C' : 'D';

	if (delta == 0) {
		return;
	}

	if (delta < 0) {
		delta = -delta;
	}

	Z_SHELL_VT100_CMD(sh, "\e[%d%c", delta, dir);
}

/* Function returns true if command length is equal to multiplicity of terminal
 * width.
 */
static inline bool full_line_cmd(const struct shell *sh)
{
	return ((sh->ctx->cmd_buff_len + z_shell_strlen(sh->ctx->prompt))
			% sh->ctx->vt100_ctx.cons.terminal_wid == 0U);
}

/* Function returns true if cursor is at beginning of an empty line. */
bool z_shell_cursor_in_empty_line(const struct shell *sh)
{
	return (((sh->ctx->cmd_buff_pos * sh->ctx->cfg.flags.echo) +
		 z_shell_strlen(sh->ctx->prompt)) %
			sh->ctx->vt100_ctx.cons.terminal_wid ==
		0U);
}

void z_shell_op_cond_next_line(const struct shell *sh)
{
	if (z_shell_cursor_in_empty_line(sh) || full_line_cmd(sh)) {
		z_cursor_next_line_move(sh);
	}
}

void z_shell_op_cursor_position_synchronize(const struct shell *sh)
{
	struct shell_multiline_cons *cons = &sh->ctx->vt100_ctx.cons;
	bool last_line;

	z_shell_multiline_data_calc(cons, sh->ctx->cmd_buff_pos,
				    sh->ctx->cmd_buff_len);
	last_line = (cons->cur_y == cons->cur_y_end);

	/* In case cursor reaches the bottom line of a terminal, it will
	 * be moved to the next line.
	 */
	if (full_line_cmd(sh)) {
		z_cursor_next_line_move(sh);
	}

	if (last_line) {
		z_shell_op_cursor_horiz_move(sh, cons->cur_x -
							       cons->cur_x_end);
	} else {
		z_shell_op_cursor_vert_move(sh, cons->cur_y_end - cons->cur_y);
		z_shell_op_cursor_horiz_move(sh, cons->cur_x -
							       cons->cur_x_end);
	}
}

void z_shell_op_cursor_move(const struct shell *sh, int16_t val)
{
	struct shell_multiline_cons *cons = &sh->ctx->vt100_ctx.cons;
	uint16_t new_pos = sh->ctx->cmd_buff_pos + val;
	int32_t row_span;
	int32_t col_span;

	z_shell_multiline_data_calc(cons, sh->ctx->cmd_buff_pos,
				    sh->ctx->cmd_buff_len);

	/* Calculate the new cursor. */
	row_span = z_row_span_with_buffer_offsets_get(
						&sh->ctx->vt100_ctx.cons,
						sh->ctx->cmd_buff_pos,
						new_pos);
	col_span = z_column_span_with_buffer_offsets_get(
						&sh->ctx->vt100_ctx.cons,
						sh->ctx->cmd_buff_pos,
						new_pos);

	z_shell_op_cursor_vert_move(sh, -row_span);
	z_shell_op_cursor_horiz_move(sh, col_span);
	sh->ctx->cmd_buff_pos = new_pos;
}

static uint16_t shift_calc(const char *str, uint16_t pos, uint16_t len, int16_t sign)
{
	bool found = false;
	uint16_t ret = 0U;
	uint16_t idx;

	while (1) {
		idx = pos + ret * sign;
		if (((idx == 0U) && (sign < 0)) ||
		    ((idx == len) && (sign > 0))) {
			break;
		}
		if (isalnum((int)str[idx]) != 0) {
			found = true;
		} else {
			if (found) {
				break;
			}
		}
		ret++;
	}

	return ret;
}

void z_shell_op_cursor_word_move(const struct shell *sh, int16_t val)
{
	int16_t shift;
	int16_t sign;

	if (val < 0) {
		val = -val;
		sign = -1;
	} else {
		sign = 1;
	}

	while (val--) {
		shift = shift_calc(sh->ctx->cmd_buff,
				   sh->ctx->cmd_buff_pos,
				   sh->ctx->cmd_buff_len, sign);
		z_shell_op_cursor_move(sh, sign * shift);
	}
}

void z_shell_op_word_remove(const struct shell *sh)
{
	/* Line must not be empty and cursor must not be at 0 to continue. */
	if ((sh->ctx->cmd_buff_len == 0) ||
	    (sh->ctx->cmd_buff_pos == 0)) {
		return;
	}

	char *str = &sh->ctx->cmd_buff[sh->ctx->cmd_buff_pos - 1];
	char *str_start = &sh->ctx->cmd_buff[0];
	uint16_t chars_to_delete;

	/* Start at the current position. */
	chars_to_delete = 0U;

	/* Look back for all spaces then for non-spaces. */
	while ((str >= str_start) && (*str == ' ')) {
		++chars_to_delete;
		--str;
	}

	while ((str >= str_start) && (*str != ' ')) {
		++chars_to_delete;
		--str;
	}

	/* Manage the buffer. */
	memmove(str + 1, str + 1 + chars_to_delete,
		sh->ctx->cmd_buff_len - chars_to_delete);
	sh->ctx->cmd_buff_len -= chars_to_delete;
	sh->ctx->cmd_buff[sh->ctx->cmd_buff_len] = '\0';

	/* Update display. */
	z_shell_op_cursor_move(sh, -chars_to_delete);
	z_cursor_save(sh);
	z_shell_fprintf(sh, SHELL_NORMAL, "%s", str + 1);
	z_clear_eos(sh);
	z_cursor_restore(sh);
}

void z_shell_op_cursor_home_move(const struct shell *sh)
{
	z_shell_op_cursor_move(sh, -sh->ctx->cmd_buff_pos);
}

void z_shell_op_cursor_end_move(const struct shell *sh)
{
	z_shell_op_cursor_move(sh, sh->ctx->cmd_buff_len -
						sh->ctx->cmd_buff_pos);
}

void z_shell_op_left_arrow(const struct shell *sh)
{
	if (sh->ctx->cmd_buff_pos > 0) {
		z_shell_op_cursor_move(sh, -1);
	}
}

void z_shell_op_right_arrow(const struct shell *sh)
{
	if (sh->ctx->cmd_buff_pos < sh->ctx->cmd_buff_len) {
		z_shell_op_cursor_move(sh, 1);
	}
}

static void reprint_from_cursor(const struct shell *sh, uint16_t diff,
				bool data_removed)
{
	/* Clear eos is needed only when newly printed command is shorter than
	 * previously printed command. This can happen when delete or backspace
	 * was called.
	 *
	 * Such condition is useful for Bluetooth devices to save number of
	 * bytes transmitted between terminal and device.
	 */
	if (data_removed) {
		z_clear_eos(sh);
	}

	if (z_flag_obscure_get(sh)) {
		int len = strlen(&sh->ctx->cmd_buff[sh->ctx->cmd_buff_pos]);

		while (len--) {
			z_shell_raw_fprintf(sh->fprintf_ctx, "*");
		}
	} else {
		z_shell_fprintf(sh, SHELL_NORMAL, "%s",
			      &sh->ctx->cmd_buff[sh->ctx->cmd_buff_pos]);
	}
	sh->ctx->cmd_buff_pos = sh->ctx->cmd_buff_len;

	if (full_line_cmd(sh)) {
		if (((data_removed) && (diff > 0)) || (!data_removed)) {
			z_cursor_next_line_move(sh);
		}
	}

	z_shell_op_cursor_move(sh, -diff);
}

static void data_insert(const struct shell *sh, const char *data, uint16_t len)
{
	uint16_t after = sh->ctx->cmd_buff_len - sh->ctx->cmd_buff_pos;
	char *curr_pos = &sh->ctx->cmd_buff[sh->ctx->cmd_buff_pos];

	if ((sh->ctx->cmd_buff_len + len) >= CONFIG_SHELL_CMD_BUFF_SIZE) {
		return;
	}

	memmove(curr_pos + len, curr_pos, after);
	memcpy(curr_pos, data, len);
	sh->ctx->cmd_buff_len += len;
	sh->ctx->cmd_buff[sh->ctx->cmd_buff_len] = '\0';

	if (!z_flag_echo_get(sh)) {
		sh->ctx->cmd_buff_pos += len;
		return;
	}

	reprint_from_cursor(sh, after, false);
}

static void char_replace(const struct shell *sh, char data)
{
	sh->ctx->cmd_buff[sh->ctx->cmd_buff_pos++] = data;

	if (!z_flag_echo_get(sh)) {
		return;
	}
	if (z_flag_obscure_get(sh)) {
		data = '*';
	}

	z_shell_raw_fprintf(sh->fprintf_ctx, "%c", data);
	if (z_shell_cursor_in_empty_line(sh)) {
		z_cursor_next_line_move(sh);
	}
}

void z_shell_op_char_insert(const struct shell *sh, char data)
{
	if (z_flag_insert_mode_get(sh) &&
	    (sh->ctx->cmd_buff_len != sh->ctx->cmd_buff_pos)) {
		char_replace(sh, data);
	} else {
		data_insert(sh, &data, 1);
	}
}

void z_shell_op_char_backspace(const struct shell *sh)
{
	if ((sh->ctx->cmd_buff_len == 0) ||
	    (sh->ctx->cmd_buff_pos == 0)) {
		return;
	}

	z_shell_op_cursor_move(sh, -1);
	z_shell_op_char_delete(sh);
}

void z_shell_op_char_delete(const struct shell *sh)
{
	uint16_t diff = sh->ctx->cmd_buff_len - sh->ctx->cmd_buff_pos;
	char *str = &sh->ctx->cmd_buff[sh->ctx->cmd_buff_pos];

	if (diff == 0U) {
		return;
	}

	memmove(str, str + 1, diff);
	--sh->ctx->cmd_buff_len;
	reprint_from_cursor(sh, --diff, true);
}

void z_shell_op_delete_from_cursor(const struct shell *sh)
{
	sh->ctx->cmd_buff_len = sh->ctx->cmd_buff_pos;
	sh->ctx->cmd_buff[sh->ctx->cmd_buff_pos] = '\0';

	z_clear_eos(sh);
}

void z_shell_op_completion_insert(const struct shell *sh,
				  const char *compl,
				  uint16_t compl_len)
{
	data_insert(sh, compl, compl_len);
}

void z_shell_cmd_line_erase(const struct shell *sh)
{
	z_shell_multiline_data_calc(&sh->ctx->vt100_ctx.cons,
				    sh->ctx->cmd_buff_pos,
				    sh->ctx->cmd_buff_len);
	z_shell_op_cursor_horiz_move(sh,
				   -(sh->ctx->vt100_ctx.cons.cur_x - 1));
	z_shell_op_cursor_vert_move(sh, sh->ctx->vt100_ctx.cons.cur_y - 1);

	z_clear_eos(sh);
}

static void print_prompt(const struct shell *sh)
{
	z_shell_fprintf(sh, SHELL_INFO, "%s", sh->ctx->prompt);
}

void z_shell_print_cmd(const struct shell *sh)
{
	int beg_offset = 0;
	int end_offset = 0;
	int cmd_width = z_shell_strlen(sh->ctx->cmd_buff);
	int adjust = sh->ctx->vt100_ctx.cons.name_len;
	char ch;

	while (cmd_width > sh->ctx->vt100_ctx.cons.terminal_wid - adjust) {
		end_offset += sh->ctx->vt100_ctx.cons.terminal_wid - adjust;
		ch = sh->ctx->cmd_buff[end_offset];
		sh->ctx->cmd_buff[end_offset] = '\0';

		z_shell_raw_fprintf(sh->fprintf_ctx, "%s\n",
				&sh->ctx->cmd_buff[beg_offset]);

		sh->ctx->cmd_buff[end_offset] = ch;
		cmd_width -= (sh->ctx->vt100_ctx.cons.terminal_wid - adjust);
		beg_offset = end_offset;
		adjust = 0;
	}
	if (cmd_width > 0) {
		z_shell_raw_fprintf(sh->fprintf_ctx, "%s",
				&sh->ctx->cmd_buff[beg_offset]);
	}
}

void z_shell_print_prompt_and_cmd(const struct shell *sh)
{
	print_prompt(sh);

	if (z_flag_echo_get(sh)) {
		z_shell_print_cmd(sh);
		z_shell_op_cursor_position_synchronize(sh);
	}
}

static void shell_pend_on_txdone(const struct shell *sh)
{
	if (IS_ENABLED(CONFIG_MULTITHREADING) &&
	    (sh->ctx->state < SHELL_STATE_PANIC_MODE_ACTIVE)) {
		struct k_poll_event event;

		k_poll_event_init(&event,
				  K_POLL_TYPE_SIGNAL,
				  K_POLL_MODE_NOTIFY_ONLY,
				  &sh->ctx->signals[SHELL_SIGNAL_TXDONE]);
		k_poll(&event, 1, K_FOREVER);
		k_poll_signal_reset(&sh->ctx->signals[SHELL_SIGNAL_TXDONE]);
	} else {
		/* Blocking wait in case of bare metal. */
		while (!z_flag_tx_rdy_get(sh)) {
		}
		z_flag_tx_rdy_set(sh, false);
	}
}

void z_shell_write(const struct shell *sh, const void *data,
		 size_t length)
{
	__ASSERT_NO_MSG(sh && data);

	size_t offset = 0;
	size_t tmp_cnt;

	while (length) {
		int err = sh->iface->api->write(sh->iface,
				&((const uint8_t *) data)[offset], length,
				&tmp_cnt);
		(void)err;
		__ASSERT_NO_MSG(err == 0);
		__ASSERT_NO_MSG(length >= tmp_cnt);
		offset += tmp_cnt;
		length -= tmp_cnt;
		if (tmp_cnt == 0 &&
		    (sh->ctx->state != SHELL_STATE_PANIC_MODE_ACTIVE)) {
			shell_pend_on_txdone(sh);
		}
	}
}

/* Function shall be only used by the fprintf module. */
void z_shell_print_stream(const void *user_ctx, const char *data, size_t len)
{
	z_shell_write((const struct shell *) user_ctx, data, len);
}

static void vt100_bgcolor_set(const struct shell *sh,
			      enum shell_vt100_color bgcolor)
{
	if (!IS_ENABLED(CONFIG_SHELL_VT100_COLORS)) {
		return;
	}

	if (bgcolor >= VT100_COLOR_END) {
		return;
	}

	if ((bgcolor == SHELL_NORMAL) ||
	    (sh->ctx->vt100_ctx.col.bgcol == bgcolor)) {
		return;
	}

	sh->ctx->vt100_ctx.col.bgcol = bgcolor;
	Z_SHELL_VT100_CMD(sh, "\e[403%dm", bgcolor);
}

void z_shell_vt100_color_set(const struct shell *sh,
			     enum shell_vt100_color color)
{
	if (!IS_ENABLED(CONFIG_SHELL_VT100_COLORS)) {
		return;
	}

	if (color >= VT100_COLOR_END) {
		return;
	}

	if (sh->ctx->vt100_ctx.col.col == color) {
		return;
	}

	sh->ctx->vt100_ctx.col.col = color;

	if (color != SHELL_NORMAL) {
		Z_SHELL_VT100_CMD(sh, "\e[1;3%dm", color);
	} else {
		Z_SHELL_VT100_CMD(sh, SHELL_VT100_MODESOFF);
	}
}

void z_shell_vt100_colors_restore(const struct shell *sh,
				  const struct shell_vt100_colors *color)
{
	if (!IS_ENABLED(CONFIG_SHELL_VT100_COLORS)) {
		return;
	}

	z_shell_vt100_color_set(sh, color->col);
	vt100_bgcolor_set(sh, color->bgcol);
}

void z_shell_vfprintf(const struct shell *sh, enum shell_vt100_color color,
		      const char *fmt, va_list args)
{
	if (IS_ENABLED(CONFIG_SHELL_VT100_COLORS) &&
	    z_flag_use_colors_get(sh)	  &&
	    (color != sh->ctx->vt100_ctx.col.col)) {
		struct shell_vt100_colors col;

		z_shell_vt100_colors_store(sh, &col);
		z_shell_vt100_color_set(sh, color);

		z_shell_fprintf_fmt(sh->fprintf_ctx, fmt, args);

		z_shell_vt100_colors_restore(sh, &col);
	} else {
		z_shell_fprintf_fmt(sh->fprintf_ctx, fmt, args);
	}
}

void z_shell_fprintf(const struct shell *sh,
		     enum shell_vt100_color color,
		     const char *fmt, ...)
{
	__ASSERT_NO_MSG(sh);
	__ASSERT_NO_MSG(sh->ctx);
	__ASSERT_NO_MSG(sh->fprintf_ctx);
	__ASSERT_NO_MSG(fmt);
	__ASSERT(z_flag_sync_mode_get(sh) || !k_is_in_isr(),
		 "Thread context required.");

	va_list args;

	va_start(args, fmt);
	z_shell_vfprintf(sh, color, fmt, args);
	va_end(args);
}
