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

#include <shell/shell_history.h>
#include <string.h>

/*
 * History must store strings (commands) and allow traversing them and adding
 * new string. When new item is added then first it is compared if it is not
 * the same as the last one (then it is not stored). If there is no room in the
 * buffer to store the new item, oldest one is removed until there is a room.
 *
 * Items are allocated and stored in the ring buffer. Items then a linked in
 * the list.
 *
 * Because stored strings must be copied and compared, it is more convenient to
 * store them in the ring buffer in a way that they are not split into two
 * chunks (when ring buffer wraps). To ensure that item is in a single chunk,
 * item includes padding. If continues area for new item cannot be allocated
 * then allocated space is increased by the padding.
 *
 * If item does not fit at the end of the ring buffer padding is added: *
 * +-----------+----------------+-----------------------------------+---------+
 * | header    | "history item" |                                   | padding |
 * | padding   |                |                                   |         |
 * +-----------+----------------+-----------------------------------+---------+
 *
 * If item fits in the ring buffer available space then there is no padding:
 * +-----------------+------------+----------------+--------------------------+
 * |                 | header     | "history item" |                          |
 * |                 | no padding |                |                          |
 * +-----------------+------------+----------------+--------------------------+
 *
 * As an optimization, the added padding is attributed to the preceding item
 * instead of the current item. This way the padding will be freed one item
 * sooner.
 */
struct shell_history_item {
	sys_dnode_t dnode;
	uint16_t len;
	uint16_t padding;
	char data[0];
};

void z_shell_history_mode_exit(struct shell_history *history)
{
	history->current = NULL;
}

bool z_shell_history_get(struct shell_history *history, bool up,
			 uint8_t *dst, uint16_t *len)
{
	struct shell_history_item *h_item; /* history item */
	sys_dnode_t *l_item; /* list item */

	if (sys_dlist_is_empty(&history->list)) {
		*len = 0U;
		return false;
	}

	if (!up) { /* button down */
		if (history->current == NULL) {
			/* Not in history mode. It is started by up button. */
			*len = 0U;

			return false;
		}

		l_item = sys_dlist_peek_prev_no_check(&history->list,
						      history->current);
	} else { /* button up */
		l_item = (history->current == NULL) ?
		sys_dlist_peek_head_not_empty(&history->list) :
		sys_dlist_peek_next_no_check(&history->list, history->current);

	}

	history->current = l_item;
	h_item = CONTAINER_OF(l_item, struct shell_history_item, dnode);

	if (l_item) {
		memcpy(dst, h_item->data, h_item->len);
		*len = h_item->len;
		dst[*len] = '\0';
		return true;
	}

	*len = 0U;
	return false;
}

static void add_to_head(struct shell_history *history,
			struct shell_history_item *item,
			uint8_t *src, size_t len, uint16_t padding)
{
	item->len = len;
	item->padding = padding;
	memcpy(item->data, src, len);
	sys_dlist_prepend(&history->list, &item->dnode);
}

/* Returns true if element was removed. */
static bool remove_from_tail(struct shell_history *history)
{
	sys_dnode_t *l_item; /* list item */
	struct shell_history_item *h_item;
	uint32_t total_len;

	if (sys_dlist_is_empty(&history->list)) {
		return false;
	}

	l_item = sys_dlist_peek_tail(&history->list);
	sys_dlist_remove(l_item);

	h_item = CONTAINER_OF(l_item, struct shell_history_item, dnode);

	total_len = offsetof(struct shell_history_item, data) +
			h_item->len + h_item->padding;
	ring_buf_get(history->ring_buf, NULL, total_len);

	return true;
}

void z_shell_history_purge(struct shell_history *history)
{
	while (remove_from_tail(history)) {
	}
}

void z_shell_history_put(struct shell_history *history, uint8_t *line,
			 size_t len)
{
	sys_dnode_t *l_item; /* list item */
	struct shell_history_item *h_item;
	uint32_t total_len = len + offsetof(struct shell_history_item, data);
	uint32_t claim_len;
	uint32_t claim2_len;
	uint16_t padding = (~total_len + 1) & (sizeof(void *) - 1);

	/* align to word. */
	total_len += padding;

	if (total_len > ring_buf_capacity_get(history->ring_buf)) {
		return;
	}

	z_shell_history_mode_exit(history);

	if (len == 0) {
		return;
	}

	l_item = sys_dlist_peek_head(&history->list);
	h_item = CONTAINER_OF(l_item, struct shell_history_item, dnode);

	if (l_item &&
	   (h_item->len == len) &&
	   (memcmp(h_item->data, line, len) == 0)) {
		/* Same command as before, do not store */
		return;
	}

	do {
		if (ring_buf_is_empty(history->ring_buf)) {
			/* if history is empty reset ring buffer. Even when
			 * ring buffer is empty, it is possible that available
			 * continues memory in worst case equals half of the
			 * ring buffer capacity. By resetting ring buffer we
			 * ensure that it is capable to provide continues memory
			 * of ring buffer capacity length.
			 */
			ring_buf_reset(history->ring_buf);
		}

		claim_len = ring_buf_put_claim(history->ring_buf,
						(uint8_t **)&h_item, total_len);
		/* second allocation may succeed if we were at the end of the
		 * buffer.
		 */
		if (claim_len < total_len) {
			claim2_len =
				ring_buf_put_claim(history->ring_buf,
						   (uint8_t **)&h_item, total_len);
			if (claim2_len == total_len) {
				/*
				 * We may get here only if a previous entry
				 * exists. Stick the excess padding to it.
				 */
				h_item->padding += claim_len;
				total_len += claim_len;
				claim_len = total_len;
			}
		}

		if (claim_len == total_len) {
			add_to_head(history, h_item, line, len, padding);
			ring_buf_put_finish(history->ring_buf, claim_len);
			break;
		}

		ring_buf_put_finish(history->ring_buf, 0);
		remove_from_tail(history);
	} while (1);
}

void z_shell_history_init(struct shell_history *history)
{
	sys_dlist_init(&history->list);
	history->current = NULL;
}
