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

#include <ztest.h>
#include <zephyr.h>
#include <sys/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 / 3600U / 1000000U) % 24;
		minute = (time / 60U / 1000000U) % 60;
		second = (time / 1000000U) % 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_msleep(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_msleep(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);
}
