/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/zephyr.h>
#include <ztest.h>


#if defined(CONFIG_ZTEST_FATAL_HOOK)
/* This is a flag indicate if treating fatal error as expected, then take
 * action dealing with it. It's SMP-safe.
 */
ZTEST_BMEM volatile bool fault_in_isr;
ZTEST_BMEM volatile k_tid_t valid_fault_tid;

static inline void reset_stored_fault_status(void)
{
	valid_fault_tid = NULL;
	fault_in_isr = false;
}

void z_impl_ztest_set_fault_valid(bool valid)
{
	if (valid) {
		if (k_is_in_isr()) {
			fault_in_isr = true;
		} else {
			valid_fault_tid = k_current_get();
		}
	} else {
		reset_stored_fault_status();
	}
}

#if defined(CONFIG_USERSPACE)
static inline void z_vrfy_ztest_set_fault_valid(bool valid)
{
	z_impl_ztest_set_fault_valid(valid);
}
#include <syscalls/ztest_set_fault_valid_mrsh.c>
#endif

__weak void ztest_post_fatal_error_hook(unsigned int reason,
		const z_arch_esf_t *pEsf)
{
}

void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf)
{
	k_tid_t curr_tid = k_current_get();
	bool valid_fault = (curr_tid == valid_fault_tid) || fault_in_isr;

	printk("Caught system error -- reason %d %d\n", reason, valid_fault);

	if (valid_fault) {
		printk("Fatal error expected as part of test case.\n");

		/* reset back to normal */
		reset_stored_fault_status();

		/* do some action after expected fatal error happened */
		ztest_post_fatal_error_hook(reason, pEsf);
	} else {
		printk("Fatal error was unexpected, aborting...\n");
		k_fatal_halt(reason);
	}
}
#endif


#if defined(CONFIG_ZTEST_ASSERT_HOOK)
/* This is a flag indicate if treating assert fail as expected, then take
 * action dealing with it. It's SMP-safe.
 */
ZTEST_BMEM volatile bool assert_in_isr;
ZTEST_BMEM volatile k_tid_t valid_assert_tid;

static inline void reset_stored_assert_status(void)
{
	valid_assert_tid = NULL;
	assert_in_isr = 0;
}

void z_impl_ztest_set_assert_valid(bool valid)
{
	if (valid) {
		if (k_is_in_isr()) {
			assert_in_isr = true;
		} else {
			valid_assert_tid = k_current_get();
		}
	} else {
		reset_stored_assert_status();
	}
}

#if defined(CONFIG_USERSPACE)
static inline void z_vrfy_ztest_set_assert_valid(bool valid)
{
	z_impl_ztest_set_assert_valid(valid);
}
#include <syscalls/ztest_set_assert_valid_mrsh.c>
#endif

__weak void ztest_post_assert_fail_hook(void)
{
	k_thread_abort(k_current_get());
}

#ifdef CONFIG_ASSERT_NO_FILE_INFO
void assert_post_action(void)
#else
void assert_post_action(const char *file, unsigned int line)
#endif
{
#ifndef CONFIG_ASSERT_NO_FILE_INFO
	ARG_UNUSED(file);
	ARG_UNUSED(line);
#endif

	printk("Caught assert failed\n");

	if ((k_current_get() == valid_assert_tid) || assert_in_isr) {
		printk("Assert error expected as part of test case.\n");

		/* reset back to normal */
		reset_stored_assert_status();

		/* It won't go back to caller when assert failed, and it
		 * will terminate the thread.
		 */
		ztest_post_assert_fail_hook();
	} else {
		printk("Assert failed was unexpected, aborting...\n");
#ifdef CONFIG_USERSPACE
	/* User threads aren't allowed to induce kernel panics; generate
	 * an oops instead.
	 */
		if (k_is_user_context()) {
			k_oops();
		}
#endif
		k_panic();
	}
}
#endif
