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

/** @file
 *  @brief Interactive shell test suite
 *
 */

#include <zephyr/kernel.h>
#include <zephyr/ztest.h>

#include <zephyr/shell/shell_history.h>

#define HIST_BUF_SIZE 160
Z_SHELL_HISTORY_DEFINE(history, HIST_BUF_SIZE);

static void init_test_buf(uint8_t *buf, size_t len, uint8_t offset)
{
	for (int i = 0; i < len; i++) {
		buf[i] = offset + i;
	}
}

/**
 * Function tests getting line from history and compares it against expected
 * result.
 */
static void test_get(bool ok, bool up, uint8_t *exp_buf, uint16_t exp_len)
{
	bool res;
	uint8_t out_buf[HIST_BUF_SIZE];
	uint16_t out_len;

	out_len = sizeof(out_buf);

	res = z_shell_history_get(&history, up, out_buf, &out_len);

	if (ok) {
		zassert_true(res, "history should contain one entry.\n");

		zassert_equal(out_len, exp_len, "Unexpected entry length.\n");
		if (out_len) {
			zassert_equal(memcmp(out_buf, exp_buf, out_len), 0,
				"Expected equal buffers.\n");
		}
	} else {
		zassert_false(res, "History should return nothing.\n");
	}
}

/* Test put line to history and get it.
 *
 * Test steps:
 * - initialize history.
 * - put line to the history.
 * - read line and verify that it is the one that was put.
 */
ZTEST(shell_test, test_history_add_get)
{
	uint8_t exp_buf[HIST_BUF_SIZE];

	init_test_buf(exp_buf, sizeof(exp_buf), 0);

	z_shell_history_init(&history);

	test_get(false, true, NULL, 0);

	z_shell_history_put(&history, exp_buf, 20);

	test_get(true, true, exp_buf, 20);

	z_shell_history_purge(&history);
}

/* Test verifies that after purging there is no line in the history. */
ZTEST(shell_test, test_history_purge)
{
	uint8_t exp_buf[HIST_BUF_SIZE];

	init_test_buf(exp_buf, sizeof(exp_buf), 0);

	z_shell_history_init(&history);

	z_shell_history_put(&history, exp_buf, 20);
	z_shell_history_put(&history, exp_buf, 20);

	z_shell_history_purge(&history);

	test_get(false, true, NULL, 0);
}

/* Test browsing history.
 *
 * Test steps:
 * - initialize history.
 * - put  lines 1,2,3 to history.
 * - get in up direction a line and verify that it's the last one added (3).
 * - get next line in up direction and verify that it's line 2.
 * - get next line in up direction and verify that it's line 1.
 * - get next line in down direction and verify that it's line 2.
 * - get next line in up direction and verify that it's line 1.
 * - get next line in down direction and verify that it's line 2.
 * - get next line in down direction and verify that it's line 3.
 * - attempt to get next line in down direction and verify that there is no
 *   line.
 */
ZTEST(shell_test, test_history_get_up_and_down)
{
	uint8_t exp1_buf[HIST_BUF_SIZE];
	uint8_t exp2_buf[HIST_BUF_SIZE];
	uint8_t exp3_buf[HIST_BUF_SIZE];

	init_test_buf(exp1_buf, sizeof(exp1_buf), 0);
	init_test_buf(exp2_buf, sizeof(exp2_buf), 10);
	init_test_buf(exp3_buf, sizeof(exp3_buf), 20);

	z_shell_history_init(&history);

	z_shell_history_put(&history, exp1_buf, 20);
	z_shell_history_put(&history, exp2_buf, 15);
	z_shell_history_put(&history, exp3_buf, 20);

	test_get(true, true, exp3_buf, 20); /* up - 3*/
	test_get(true, true, exp2_buf, 15); /* up - 2*/
	test_get(true, true, exp1_buf, 20); /* up - 1*/
	test_get(true, false, exp2_buf, 15); /* down - 2 */
	test_get(true, true, exp1_buf, 20);  /* up - 1*/
	test_get(true, false, exp2_buf, 15); /* down - 2 */
	test_get(true, false, exp3_buf, 20); /* down - 3 */
	test_get(false, false, NULL, 0); /* down - nothing */

	z_shell_history_purge(&history);
}

/* Function for getting maximal buffer size that can be stored in the history */
static int get_max_buffer_len(void)
{
	uint8_t buf[HIST_BUF_SIZE];
	uint8_t out_buf[HIST_BUF_SIZE];
	int len = sizeof(buf);
	uint16_t out_len;

	z_shell_history_init(&history);

	do {
		z_shell_history_put(&history, buf, len);
		out_len = sizeof(out_buf);
		if (z_shell_history_get(&history, true, out_buf, &out_len)) {
			z_shell_history_purge(&history);
			break;
		}
	} while (len--);

	return len;
}

/* Test verifies that line that cannot fit into history buffer is not stored.
 *
 * Test steps:
 * - initialize history.
 * - put buffer that is bigger than history overall capacity.
 * - verify that history is empty.
 * - put short line followed by line that is close to max.
 * - verify that long line evicted first line from history.
 */
ZTEST(shell_test, test_too_long_line_not_stored)
{
	uint8_t exp1_buf[HIST_BUF_SIZE];
	int max_len = get_max_buffer_len();

	init_test_buf(exp1_buf, sizeof(exp1_buf), 0);
	z_shell_history_init(&history);

	z_shell_history_put(&history, exp1_buf, max_len + 1);

	/*validate that nothing is stored */
	test_get(false, true, NULL, 0); /* empty */

	z_shell_history_put(&history, exp1_buf, 20);
	z_shell_history_put(&history, exp1_buf, max_len - 10);

	/* Test that long entry evicts older entry. */
	test_get(true, true, exp1_buf, max_len - 10);
	test_get(false, true, NULL, 0); /* only one entry */

	z_shell_history_purge(&history);
}

/* Test verifies that same line as the previous one is not stored in the
 * history.
 *
 * Test steps:
 * - initialize history.
 * - put same line twice.
 * - verify that only one line is in the history.
 */
ZTEST(shell_test, test_no_duplicates_in_a_row)
{
	uint8_t exp1_buf[HIST_BUF_SIZE];

	init_test_buf(exp1_buf, sizeof(exp1_buf), 0);
	z_shell_history_init(&history);

	z_shell_history_put(&history, exp1_buf, 20);
	z_shell_history_put(&history, exp1_buf, 20);

	test_get(true, true, exp1_buf, 20);
	/* only one line stored. */
	test_get(false, true, NULL, 0);

	z_shell_history_purge(&history);
}

/* Test storing long lines in the history.
 *
 * * Test steps:
 * - initialize history.
 * - Put max length line 1 in history.
 * - Verify that it is present.
 * - Put max length line 2 in history.
 * - Verify that line 2 is present and line 1 was evicted.
 * - Put max length line 3 in history.
 * - Verify that line 3 is present and line 2 was evicted.
 */
ZTEST(shell_test, test_storing_long_buffers)
{
	uint8_t exp1_buf[HIST_BUF_SIZE];
	uint8_t exp2_buf[HIST_BUF_SIZE];
	uint8_t exp3_buf[HIST_BUF_SIZE];
	int max_len = get_max_buffer_len();

	init_test_buf(exp1_buf, sizeof(exp1_buf), 0);
	init_test_buf(exp2_buf, sizeof(exp2_buf), 10);
	init_test_buf(exp3_buf, sizeof(exp3_buf), 20);

	z_shell_history_init(&history);

	z_shell_history_put(&history, exp1_buf, max_len);
	test_get(true, true, exp1_buf, max_len);
	test_get(false, true, NULL, 0); /* only one entry */

	z_shell_history_put(&history, exp2_buf, max_len);
	test_get(true, true, exp2_buf, max_len);
	test_get(false, true, NULL, 0); /* only one entry */

	z_shell_history_put(&history, exp3_buf, max_len);
	test_get(true, true, exp3_buf, max_len);
	test_get(false, true, NULL, 0); /* only one entry */

	z_shell_history_purge(&history);
}

ZTEST_SUITE(shell_test, NULL, NULL, NULL, NULL, NULL);
