/*
 * Copyright (c) 2017-2018 Oticon A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include "init.h"
#include <stdint.h>
#include <string.h>
#include "bs_types.h"
#include "bs_tracing.h"
#include "bstests.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 = 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 = 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(struct device *arg)
{
	ARG_UNUSED(arg);
	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(struct device *arg)
{
	ARG_UNUSED(arg);
	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;
	}

	return bst_result;
}
