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

#include <ztest.h>
#include <zephyr.h>
#include <misc/printk.h>

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#include "timer_model.h"
#include "native_rtc.h"

#include <stdio.h>

static char *us_time_to_str(char *dest, u64_t time)
{
	if (time != NEVER) {
		unsigned int hour;
		unsigned int minute;
		unsigned int second;
		unsigned int us;

		hour   = (time / 3600 / 1000000) % 24;
		minute = (time / 60 / 1000000) % 60;
		second = (time / 1000000) % 60;
		us     = time % 1000000;

		sprintf(dest, "%02u:%02u:%02u.%06u", hour, minute, second, us);
	} else {
		sprintf(dest, " NEVER/UNKNOWN ");

	}
	return dest;
}

#define WAIT_TIME 250 /* ms */
#define TOLERANCE 20 /* ms Tolerance in native_posix time after WAIT_TIME */
#define TICK_MS (1000ul / CONFIG_SYS_CLOCK_TICKS_PER_SEC)

/**
 * @brief Test native_posix real time control
 */
static void test_realtime(void)
{
	extern u64_t get_host_us_time(void);
	u64_t time;
	char time_s[60];
	u64_t end_time, start_time;
	s64_t diff, error;
	u64_t start_rtc_time[3];
	double acc_ratio = 1;
	double time_ratios[5] = {0.25, 2, 2, 2, 2};
	/* This ratio adjustments lead to test speeds 0.25x, 0.5x, 1x, 2x & 4x*/

	time = native_rtc_gettime_us(RTC_CLOCK_REALTIME);

	us_time_to_str(time_s, time);
	printk("Booted @%s\n", time_s);

	/*
	 * We override the real time speed in case it was set from command
	 * line
	 */
	hwtimer_set_rt_ratio(1.0);

	/*Let's wait >=1 tick to ensure everything is settled*/
	k_sleep(TICK_MS);

	start_time = get_host_us_time();
	start_rtc_time[2] = native_rtc_gettime_us(RTC_CLOCK_PSEUDOHOSTREALTIME);
	start_rtc_time[0] = native_rtc_gettime_us(RTC_CLOCK_BOOT);
	start_rtc_time[1] = native_rtc_gettime_us(RTC_CLOCK_REALTIME);

	for (int i = 0; i < 5; i++) {
		native_rtc_adjust_clock(time_ratios[i]);
		acc_ratio *= time_ratios[i];

		/* k_sleep waits 1 tick more than asked */
		k_sleep(WAIT_TIME - TICK_MS);

		/*
		 * Check that during the sleep, the correct amount of real time
		 * passed
		 */
		end_time = get_host_us_time();
		diff = end_time - start_time;
		error = diff / 1000 - WAIT_TIME / acc_ratio;

		posix_print_trace("%i/5: Speed ratio %.2f. Took %.3fms. "
				"Should take %.3fms +- %ims\n",
				i+1,
				acc_ratio,
				diff / 1000.0,
				WAIT_TIME / acc_ratio,
				TOLERANCE);

		zassert_true(abs(error) < TOLERANCE,
			     "Real time error over TOLERANCE");

		/*
		 * Check that the RTC clocks advanced WAIT_TIME
		 * independently of the real timeness ratio
		 */
		diff = native_rtc_gettime_us(RTC_CLOCK_PSEUDOHOSTREALTIME) -
			start_rtc_time[2];
		error = diff - WAIT_TIME * 1000;

		posix_print_trace("%i/5: PSEUDOHOSTREALTIME reports %.3fms "
				"(error %.3fms)\n",
				i+1,
				diff / 1000.0,
				error / 1000.0);

		error /= 1000;
		zassert_true(abs(error) < TOLERANCE,
			     "PSEUDOHOSTREALTIME time error over TOLERANCE");

		diff = native_rtc_gettime_us(RTC_CLOCK_BOOT) -
			start_rtc_time[0];

		zassert_true(diff == WAIT_TIME * 1000,
				"Error in RTC_CLOCK_BOOT");

		diff = native_rtc_gettime_us(RTC_CLOCK_REALTIME) -
			start_rtc_time[1];

		zassert_true(diff == WAIT_TIME * 1000,
				"Error in RTC_CLOCK_REALTIME");

		start_time += WAIT_TIME * 1000 / acc_ratio;
		start_rtc_time[0] += WAIT_TIME * 1000;
		start_rtc_time[1] += WAIT_TIME * 1000;
		start_rtc_time[2] += WAIT_TIME * 1000;
	}

}

/**
 * @brief Test native_posix RTC offset functionality
 */
static void test_rtc_offset(void)
{
	int offset = 567;
	u64_t start_rtc_time[2];
	s64_t diff, error;

	start_rtc_time[0] = native_rtc_gettime_us(RTC_CLOCK_REALTIME);
	start_rtc_time[1] = native_rtc_gettime_us(RTC_CLOCK_PSEUDOHOSTREALTIME);
	native_rtc_offset(offset);
	diff = native_rtc_gettime_us(RTC_CLOCK_PSEUDOHOSTREALTIME)
		- start_rtc_time[1];

	error = diff - offset;
	zassert_true(abs(error) < TOLERANCE,
		     "PSEUDOHOSTREALTIME offset error over TOLERANCE");

	diff = native_rtc_gettime_us(RTC_CLOCK_REALTIME) - start_rtc_time[0];

	zassert_true(diff == offset, "Offseting RTC failed\n");
}

void test_main(void)
{
	ztest_test_suite(native_realtime_tests,
		ztest_unit_test(test_realtime),
		ztest_unit_test(test_rtc_offset)
	);

	ztest_run_test_suite(native_realtime_tests);
}
