/*
 * Copyright (c) 2017 Oticon A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * Reduced set of HW models sufficient to run some of the sample apps
 * and regression tests
 */

#include <stdint.h>
#include <signal.h>
#include <stddef.h>
#include <stdlib.h>
#include <pthread.h>
#include "hw_models_top.h"
#include "timer_model.h"
#include "irq_ctrl.h"
#include "posix_board_if.h"
#include "hw_counter.h"
#include <arch/posix/posix_soc_if.h>
#include "posix_arch_internal.h"
#include "sdl_events.h"
#include <sys/util.h>


static uint64_t simu_time; /* The actual time as known by the HW models */
static uint64_t end_of_time = NEVER; /* When will this device stop */

/* List of HW model timers: */
extern uint64_t hw_timer_timer; /* When should this timer_model be called */
extern uint64_t irq_ctrl_timer;
extern uint64_t hw_counter_timer;
#ifdef CONFIG_HAS_SDL
extern uint64_t sdl_event_timer;
#endif

static enum {
	HWTIMER = 0,
	IRQCNT,
	HW_COUNTER,
#ifdef CONFIG_HAS_SDL
	SDLEVENTTIMER,
#endif
	NUMBER_OF_TIMERS,
	NONE
} next_timer_index = NONE;

static uint64_t *Timer_list[NUMBER_OF_TIMERS] = {
	&hw_timer_timer,
	&irq_ctrl_timer,
	&hw_counter_timer,
#ifdef CONFIG_HAS_SDL
	&sdl_event_timer,
#endif
};

static uint64_t next_timer_time;

/* Have we received a SIGTERM or SIGINT */
static volatile sig_atomic_t signaled_end;

/**
 * Handler for SIGTERM and SIGINT
 */
void hwm_signal_end_handler(int sig)
{
	signaled_end = 1;
}

/**
 * Set the handler for SIGTERM and SIGINT which will cause the
 * program to exit gracefully when they are received the 1st time
 *
 * Note that our handler only sets a variable indicating the signal was
 * received, and in each iteration of the hw main loop this variable is
 * evaluated.
 * If for some reason (the program is stuck) we never evaluate it, the program
 * would never exit.
 * Therefore we set SA_RESETHAND: This way, the 2nd time the signal is received
 * the default handler would be called to terminate the program no matter what.
 *
 * Note that SA_RESETHAND requires either _POSIX_C_SOURCE>=200809 or
 * _XOPEN_SOURCE>=500
 */
void hwm_set_sig_handler(void)
{
	struct sigaction act;

	act.sa_handler = hwm_signal_end_handler;
	PC_SAFE_CALL(sigemptyset(&act.sa_mask));

	act.sa_flags = SA_RESETHAND;

	PC_SAFE_CALL(sigaction(SIGTERM, &act, NULL));
	PC_SAFE_CALL(sigaction(SIGINT, &act, NULL));
}


static void hwm_sleep_until_next_timer(void)
{
	if (next_timer_time >= simu_time) { /* LCOV_EXCL_BR_LINE */
		simu_time = next_timer_time;
	} else {
		/* LCOV_EXCL_START */
		posix_print_warning("next_timer_time corrupted (%"PRIu64"<= %"
				PRIu64", timer idx=%i)\n",
				(uint64_t)next_timer_time,
				(uint64_t)simu_time,
				next_timer_index);
		/* LCOV_EXCL_STOP */
	}

	if (signaled_end || (simu_time > end_of_time)) {
		posix_print_trace("\nStopped at %.3Lfs\n",
				((long double)simu_time)/1.0e6L);
		posix_exit(0);
	}
}


/**
 * Find in between all timers which is the next one
 * and update  next_timer_* accordingly
 */
void hwm_find_next_timer(void)
{
	next_timer_index = 0;
	next_timer_time  = *Timer_list[0];

	for (unsigned int i = 1; i < NUMBER_OF_TIMERS ; i++) {
		if (next_timer_time > *Timer_list[i]) {
			next_timer_index = i;
			next_timer_time = *Timer_list[i];
		}
	}
}

/**
 * Entry point for the HW models
 * The HW models execute in an infinite loop until terminated
 */
void hwm_main_loop(void)
{
	while (1) {
		hwm_sleep_until_next_timer();

		switch (next_timer_index) { /* LCOV_EXCL_BR_LINE */
		case HWTIMER:
			hwtimer_timer_reached();
			break;
		case IRQCNT:
			hw_irq_ctrl_timer_triggered();
			break;
		case HW_COUNTER:
			hw_counter_triggered();
			break;
#ifdef CONFIG_HAS_SDL
		case SDLEVENTTIMER:
			sdl_handle_events();
			break;
#endif
		default:
			/* LCOV_EXCL_START */
			posix_print_error_and_exit(
					"next_timer_index corrupted\n");
			break;
			/* LCOV_EXCL_STOP */
		}

		hwm_find_next_timer();
	}
}

/**
 * Set the simulated time when the process will stop
 */
void hwm_set_end_of_time(uint64_t new_end_of_time)
{
	end_of_time = new_end_of_time;
}

/**
 * Return the current time as known by the device
 */
uint64_t hwm_get_time(void)
{
	return simu_time;
}

uint64_t posix_get_hw_cycle(void)
{
	return hwm_get_time();
}

/**
 * Function to initialize the HW models
 */
void hwm_init(void)
{
	hwm_set_sig_handler();
	hwtimer_init();
	hw_counter_init();
	hw_irq_ctrl_init();

	hwm_find_next_timer();
}

/**
 * Function to free any resources allocated by the HW models
 * Note that this function needs to be designed so it is possible
 * to call it more than once during cleanup
 */
void hwm_cleanup(void)
{
	hwtimer_cleanup();
	hw_irq_ctrl_cleanup();
}
