/*
 * Copyright (c) 2022 Google LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "cmdline.h" /* native_posix command line options header */
#include "soc.h"
#include "tc_util.h"
#include "ztest_test_new.h"

static const char *test_args;
static bool list_tests;

static void add_test_filter_option(void)
{
	static struct args_struct_t test_filter_s[] = {
		/*
		 * Fields:
		 * manual, mandatory, switch,
		 * option_name, var_name ,type,
		 * destination, callback,
		 * description
		 */
		{ false, false, true, "list", NULL, 'b', (void *)&list_tests, NULL,
		  "List all suite and test cases" },
		{ false, false, false, "test", "suite::test", 's', (void *)&test_args, NULL,
		  "Name of tests to run. Comma separated list formatted as "
		  "\'suiteA::test1,suiteA::test2,suiteB::*\'. An * can be used "
		  "as a wildcard to run all tests within a suite." },
		ARG_TABLE_ENDMARKER
	};

	native_add_command_line_opts(test_filter_s);
}

NATIVE_TASK(add_test_filter_option, PRE_BOOT_1, 10);

/**
 * @brief Try to shorten a filename by removing the current directory
 *
 * This helps to reduce the very long filenames in assertion failures. It
 * removes the current directory from the filename and returns the rest.
 * This makes assertions a lot more readable, and sometimes they fit on one
 * line.
 *
 * Overrides implementation in ztest_new.c
 *
 * @param file Filename to check
 * @returns Shortened filename, or @file if it could not be shortened
 */
const char *ztest_relative_filename(const char *file)
{
	const char *cwd;
	char buf[200];

	cwd = getcwd(buf, sizeof(buf));
	if (cwd && strlen(file) > strlen(cwd) && !strncmp(file, cwd, strlen(cwd))) {
		return file + strlen(cwd) + 1; /* move past the trailing '/' */
	}
	return file;
}

/**
 * @brief Helper function to set list_tests
 *
 * @param value - Sets list_tests to value
 */
void ztest_set_list_test(bool value)
{
	list_tests = value;
}

/**
 * @brief Helper function to get command line argument for listing tests
 *
 * @return true
 * @return false
 */
bool z_ztest_get_list_test(void)
{
	return list_tests;
}

/**
 * @brief Helper function to get command line test arguments
 *
 * @return const char*
 */
const char *ztest_get_test_args(void)
{
	return test_args;
}

/**
 * @brief Lists registered unit tests in this binary, one per line
 *
 * @return int Number of tests in binary
 */
int z_ztest_list_tests(void)
{
	struct ztest_suite_node *ptr;
	struct ztest_unit_test *test = NULL;
	int test_count = 0;

	for (ptr = _ztest_suite_node_list_start; ptr < _ztest_suite_node_list_end; ++ptr) {
		test = NULL;
		while ((test = z_ztest_get_next_test(ptr->name, test)) != NULL) {
			TC_PRINT("%s::%s\n", test->test_suite_name, test->name);
			test_count++;
		}
	}

	/* List tests only once */
	ztest_set_list_test(false);
	return test_count;
}

/**
 * Default entry point for running or listing registered unit tests.
 *
 * @param state The current state of the machine as it relates to the test executable.
 */
void z_ztest_run_all(const void *state)
{
	if (z_ztest_get_list_test()) {
		z_ztest_list_tests();
	} else {
		ztest_run_test_suites(state);
		ztest_verify_all_test_suites_ran();
	}
}

/**
 * @brief Checks if the test_args contains the suite/test name.
 *
 * @param suite_name
 * @param test_name
 * @return true
 * @return false
 */
static bool z_ztest_testargs_contains(const char *suite_name, const char *test_name)
{
	bool found = false;
	char *test_args_local = strdup(test_args);
	char *suite_test_pair;
	char *last_suite_test_pair;
	char *suite_arg;
	char *test_arg;
	char *last_arg;

	suite_test_pair = strtok_r(test_args_local, ",", &last_suite_test_pair);

	while (suite_test_pair && !found) {
		suite_arg = strtok_r(suite_test_pair, ":", &last_arg);
		test_arg = strtok_r(NULL, ":", &last_arg);

		found = !strcmp(suite_arg, suite_name);
		if (test_name) {
			found &= !strcmp(test_arg, "*") ||
				 !strcmp(test_arg, test_name);
		}

		suite_test_pair = strtok_r(NULL, ",", &last_suite_test_pair);
	}

	free(test_args_local);
	return found;
}

/**
 * @brief Determines if the test case should run based on test cases listed
 *	  in the command line argument.
 *
 * Overrides implementation in ztest_new.c
 *
 * @param suite - name of test suite
 * @param test  - name of unit test
 * @return true
 * @return false
 */
bool z_ztest_should_test_run(const char *suite, const char *test)
{
	bool run_test = false;

	run_test = (test_args == NULL ||
		    z_ztest_testargs_contains(suite, test));

	return run_test;
}

/**
 * @brief Determines if the test suite should run based on test cases listed
 *	  in the command line argument.
 *
 * Overrides implementation in ztest_new.c
 *
 * @param state The current state of the machine as it relates to the test
 *		executable.
 * @param suite Pointer to ztest_suite_node
 * @return true
 * @return false
 */
bool z_ztest_should_suite_run(const void *state, struct ztest_suite_node *suite)
{
	bool run_suite = true;

	if (test_args != NULL && !z_ztest_testargs_contains(suite->name, NULL)) {
		run_suite = false;
		suite->stats->run_count++;
	} else if (suite->predicate != NULL) {
		run_suite = suite->predicate(state);
	}

	return run_suite;
}

ZTEST_DMEM const struct ztest_arch_api ztest_api = {
	.run_all = z_ztest_run_all,
	.should_suite_run = z_ztest_should_suite_run,
	.should_test_run = z_ztest_should_test_run
};
