/*
 * Copyright (c) 2017-2018 Oticon A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/init.h>
#include <stdint.h>
#include <string.h>
#include "bs_types.h"
#include "bs_tracing.h"
#include "bstests.h"
#include "bs_oswrap.h"

/*
 * Result of the testcase execution.
 * Note that the executable will return the maximum of bst_result and
 * {the HW model return code} to the shell and that
 * {the HW model return code} will be 0 unless it fails or it is
 * configured illegally
 */
enum bst_result_t bst_result;

static struct bst_test_instance *current_test;
static struct bst_test_list *test_list_top;

__attribute__((weak)) bst_test_install_t test_installers[] = { NULL };

struct bst_test_list *bst_add_tests(struct bst_test_list *tests,
				const struct bst_test_instance *test_def)
{
	int idx = 0;
	struct bst_test_list *tail = tests;
	struct bst_test_list *head = tests;

	if (tail) {
		/* First we 'run to end' */
		while (tail->next) {
			tail = tail->next;
		}
	} else {
		if (test_def[idx].test_id != NULL) {
			head = bs_malloc(sizeof(struct bst_test_list));
			head->next = NULL;
			head->test_instance = (struct bst_test_instance *)
						&test_def[idx++];
			tail = head;
		}
	}

	while (test_def[idx].test_id != NULL) {
		tail->next = bs_malloc(sizeof(struct bst_test_list));
		tail = tail->next;
		tail->test_instance = (struct bst_test_instance *)
					&test_def[idx++];
		tail->next = NULL;
	}

	return head;
}

static struct bst_test_instance *bst_test_find(struct bst_test_list *tests,
					  char *test_id)
{
	struct bst_test_list *top = tests;

	while (top != NULL) {
		if (!strcmp(top->test_instance->test_id, test_id)) {
			/* Match found */
			return top->test_instance;
		}
		top = top->next;
	}
	return NULL;
}

void bst_install_tests(void)
{
	int idx = 0;

	if (test_list_top) {
		/* Tests were already installed */
		return;
	}

	/* First execute installers until first test was installed */
	while (!test_list_top && test_installers[idx]) {
		test_list_top = test_installers[idx++](test_list_top);
	}

	/* After that simply add remaining tests to list */
	while (test_installers[idx]) {
		test_installers[idx++](test_list_top);
	}
}

/**
 * Print the tests list displayed with the --testslist command
 * line option
 */
void bst_print_testslist(void)
{
	struct bst_test_list *top;

	/* Install tests */
	bst_install_tests();

	top = test_list_top;
	while (top) {
		bs_trace_raw(0, "TestID: %-10s\t%s\n",
			     top->test_instance->test_id,
			     top->test_instance->test_descr);
		top = top->next;
	}
}

/**
 * Select the testcase to be run from its id
 */
void bst_set_testapp_mode(char *test_id)
{
	/* Install tests */
	bst_install_tests();

	/* By default all tests start as in progress */
	bst_result = In_progress;

	current_test = bst_test_find(test_list_top, test_id);
	if (!current_test) {
		bs_trace_error_line("test id %s doesn't exist\n", test_id);
	}
}

/**
 * Pass to the testcase the command line arguments it may have
 *
 * This function is called after bst_set_testapp_mode
 * and before *init_f
 */
void bst_pass_args(int argc, char **argv)
{
	if (current_test && current_test->test_args_f) {
		current_test->test_args_f(argc, argv);
	}
}

/**
 * Will be called before the CPU is booted
 */
void bst_pre_init(void)
{
	if (current_test && current_test->test_pre_init_f) {
		current_test->test_pre_init_f();
	}
}

/**
 * Will be called when the CPU has gone to sleep for the first time
 */
void bst_post_init(void)
{
	if (current_test && current_test->test_post_init_f) {
		current_test->test_post_init_f();
	}
}

/**
 * Will be called each time the bstest_ticker timer is triggered
 */
void bst_tick(bs_time_t time)
{

	if (current_test == NULL) {
		return;
	}

	if (current_test->test_tick_f) {
		current_test->test_tick_f(time);
	} else if (current_test->test_id) {
		bs_trace_error_line("the test id %s doesn't have a tick handler"
				    " (how come did we arrive here?)\n",
				    current_test->test_id);
	}

}

bool bst_irq_sniffer(int irq_number)
{
	if (current_test && current_test->test_irq_sniffer_f) {
		return current_test->test_irq_sniffer_f(irq_number);
	} else {
		return false;
	}
}

static int bst_fake_device_driver_pre2_init(void)
{
	if (current_test && current_test->test_fake_ddriver_prekernel_f) {
		current_test->test_fake_ddriver_prekernel_f();
	}
	return 0;
}

static int bst_fake_device_driver_post_init(void)
{
	if (current_test && current_test->test_fake_ddriver_postkernel_f) {
		current_test->test_fake_ddriver_postkernel_f();
	}
	return 0;
}

SYS_INIT(bst_fake_device_driver_pre2_init, PRE_KERNEL_1, 0);
SYS_INIT(bst_fake_device_driver_post_init, POST_KERNEL, 0);

void bst_main(void)
{
	if (current_test && current_test->test_main_f) {
		current_test->test_main_f();
	}
}

/**
 * Will be called when the device is being terminated
 */
uint8_t bst_delete(void)
{
	if (current_test && current_test->test_delete_f) {
		current_test->test_delete_f();
	}

	while (test_list_top) {
		struct bst_test_list *tmp = test_list_top->next;

		free(test_list_top);
		test_list_top = tmp;
	}

	if (bst_result == In_progress) {
		bs_trace_raw_time(2, "TESTCASE NOT PASSED at exit (test return "
				  "(%u) indicates it was still in progress)\n", bst_result);
	} else if (bst_result != Passed) {
		bs_trace_raw_time(2, "The TESTCASE FAILED (test return code %u)\n",
				  bst_result);
	}

	return bst_result;
}

#if defined(CONFIG_NATIVE_SIMULATOR_MCU_N)
#include "bstest_ticker.h"

void bst_ticker_set_period(bs_time_t tick_period)
{
	bst_ticker_amp_set_period(CONFIG_NATIVE_SIMULATOR_MCU_N, tick_period);
}

void bst_ticker_set_next_tick_absolute(bs_time_t time)
{
	bst_ticker_amp_set_next_tick_absolutelute(CONFIG_NATIVE_SIMULATOR_MCU_N, time);
}

void bst_ticker_set_next_tick_delta(bs_time_t time)
{
	bst_ticker_amp_set_next_tick_delta(CONFIG_NATIVE_SIMULATOR_MCU_N, time);
}

void bst_awake_cpu_asap(void)
{
	bst_ticker_amp_awake_cpu_asap(CONFIG_NATIVE_SIMULATOR_MCU_N);
}

#endif /* defined(CONFIG_NATIVE_SIMULATOR_MCU_N) */
