/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "test_timer.h"
#include <ztest.h>

#define DURATION 100
#define PERIOD 50
#define EXPIRE_TIMES 4
static void duration_expire(struct k_timer *timer);
static void duration_stop(struct k_timer *timer);

/** TESTPOINT: init timer via K_TIMER_DEFINE */
K_TIMER_DEFINE(ktimer, duration_expire, duration_stop);
static struct k_timer timer;
static struct timer_data tdata;

#define TIMER_ASSERT(exp, tmr)			 \
	do {					 \
		if (!(exp)) {			 \
			k_timer_stop(tmr);	 \
			zassert_true(exp, NULL); \
		}				 \
	} while (0)

static void init_timer_data(void)
{
	tdata.expire_cnt = 0;
	tdata.stop_cnt = 0;
}

/* entry routines */
static void duration_expire(struct k_timer *timer)
{
	/** TESTPOINT: expire function */
	tdata.expire_cnt++;
	if (tdata.expire_cnt == 1) {
		TIMER_ASSERT(k_uptime_delta(&tdata.timestamp) >= DURATION,
			     timer);
	} else {
		TIMER_ASSERT(k_uptime_delta(&tdata.timestamp) >= PERIOD, timer);
	}

	tdata.timestamp = k_uptime_get();
	if (tdata.expire_cnt >= EXPIRE_TIMES) {
		k_timer_stop(timer);
	}
}

static void duration_stop(struct k_timer *timer)
{
	tdata.stop_cnt++;
}

static void period0_expire(struct k_timer *timer)
{
	tdata.expire_cnt++;
}

static void status_expire(struct k_timer *timer)
{
	/** TESTPOINT: status get upon timer expired */
	TIMER_ASSERT(k_timer_status_get(timer) == 1, timer);
	/** TESTPOINT: remaining get upon timer expired */
	TIMER_ASSERT(k_timer_remaining_get(timer) >= PERIOD, timer);

	if (tdata.expire_cnt >= EXPIRE_TIMES) {
		k_timer_stop(timer);
	}
}

static void busy_wait_ms(s32_t ms)
{
	k_busy_wait(ms*1000);
}

static void status_stop(struct k_timer *timer)
{
	/** TESTPOINT: remaining get upon timer stopped */
	TIMER_ASSERT(k_timer_remaining_get(timer) == 0, timer);
}

/* test cases */
void test_timer_duration_period(void)
{
	init_timer_data();
	/** TESTPOINT: init timer via k_timer_init */
	k_timer_init(&timer, duration_expire, duration_stop);
	k_timer_start(&timer, DURATION, PERIOD);
	tdata.timestamp = k_uptime_get();
	busy_wait_ms(DURATION + PERIOD * EXPIRE_TIMES + PERIOD / 2);
	/** TESTPOINT: check expire and stop times */
	TIMER_ASSERT(tdata.expire_cnt == EXPIRE_TIMES, &timer);
	TIMER_ASSERT(tdata.stop_cnt == 1, &timer);

	/* cleanup environemtn */
	k_timer_stop(&timer);
}

void test_timer_period_0(void)
{
	init_timer_data();
	/** TESTPOINT: set period 0 */
	k_timer_init(&timer, period0_expire, NULL);
	k_timer_start(&timer, DURATION, 0);
	tdata.timestamp = k_uptime_get();
	busy_wait_ms(DURATION + 1);

	/** TESTPOINT: ensure it is one-short timer */
	TIMER_ASSERT(tdata.expire_cnt == 1, &timer);
	TIMER_ASSERT(tdata.stop_cnt == 0, &timer);

	/* cleanup environemtn */
	k_timer_stop(&timer);
}

void test_timer_expirefn_null(void)
{
	init_timer_data();
	/** TESTPOINT: expire function NULL */
	k_timer_init(&timer, NULL, duration_stop);
	k_timer_start(&timer, DURATION, PERIOD);
	busy_wait_ms(DURATION + PERIOD * EXPIRE_TIMES + PERIOD / 2);

	k_timer_stop(&timer);
	/** TESTPOINT: expire handler is not invoked */
	TIMER_ASSERT(tdata.expire_cnt == 0, &timer);
	/** TESTPOINT: stop handler is invoked */
	TIMER_ASSERT(tdata.stop_cnt == 1, &timer);

	/* cleanup environment */
	k_timer_stop(&timer);
}

void test_timer_status_get(void)
{
	init_timer_data();
	k_timer_init(&timer, status_expire, status_stop);
	k_timer_start(&timer, DURATION, PERIOD);
	/** TESTPOINT: status get upon timer starts */
	TIMER_ASSERT(k_timer_status_get(&timer) == 0, &timer);
	/** TESTPOINT: remaining get upon timer starts */
	TIMER_ASSERT(k_timer_remaining_get(&timer) >= DURATION / 2, &timer);

	/* cleanup environment */
	k_timer_stop(&timer);
}

void test_timer_status_get_anytime(void)
{
	init_timer_data();
	k_timer_init(&timer, NULL, NULL);
	k_timer_start(&timer, DURATION, PERIOD);
	busy_wait_ms(DURATION + PERIOD * (EXPIRE_TIMES - 1) + PERIOD / 2);

	/** TESTPOINT: status get at any time */
	TIMER_ASSERT(k_timer_status_get(&timer) == EXPIRE_TIMES, &timer);

	/* cleanup environment */
	k_timer_stop(&timer);
}

void test_timer_status_sync(void)
{
	init_timer_data();
	k_timer_init(&timer, duration_expire, duration_stop);
	k_timer_start(&timer, DURATION, PERIOD);

	for (int i = 0; i < EXPIRE_TIMES; i++) {
		/** TESTPOINT: check timer not expire */
		TIMER_ASSERT(tdata.expire_cnt == i, &timer);
		/** TESTPOINT： expired times returned by status sync */
		TIMER_ASSERT(k_timer_status_sync(&timer) == 1, &timer);
		/** TESTPOINT: check timer not expire */
		TIMER_ASSERT(tdata.expire_cnt == (i + 1), &timer);
	}

	/* cleanup environment */
	k_timer_stop(&timer);
}

void test_timer_k_define(void)
{
	init_timer_data();
	/** TESTPOINT: init timer via k_timer_init */
	k_timer_start(&ktimer, DURATION, PERIOD);
	tdata.timestamp = k_uptime_get();
	busy_wait_ms(DURATION + PERIOD * EXPIRE_TIMES + PERIOD / 2);

	/** TESTPOINT: check expire and stop times */
	TIMER_ASSERT(tdata.expire_cnt == EXPIRE_TIMES, &ktimer);
	TIMER_ASSERT(tdata.stop_cnt == 1, &ktimer);

	/* cleanup environment */
	k_timer_stop(&ktimer);
}

/* k_timer_user_data_set/get test */

static void user_data_timer_handler(struct k_timer *timer);

K_TIMER_DEFINE(timer0, user_data_timer_handler, NULL);
K_TIMER_DEFINE(timer1, user_data_timer_handler, NULL);
K_TIMER_DEFINE(timer2, user_data_timer_handler, NULL);
K_TIMER_DEFINE(timer3, user_data_timer_handler, NULL);
K_TIMER_DEFINE(timer4, user_data_timer_handler, NULL);

static struct k_timer *user_data_timer[5] = {
	&timer0, &timer1, &timer2, &timer3, &timer4
};

static const intptr_t user_data[5] = { 0x1337, 0xbabe, 0xd00d, 0xdeaf, 0xfade };

static int user_data_correct[5] = { 0, 0, 0, 0, 0 };

static void user_data_timer_handler(struct k_timer *timer)
{
	int timer_num = timer == user_data_timer[0] ? 0 :
			timer == user_data_timer[1] ? 1 :
			timer == user_data_timer[2] ? 2 :
			timer == user_data_timer[3] ? 3 :
			timer == user_data_timer[4] ? 4 : -1;

	if (timer_num == -1) {
		return;
	}

	intptr_t data_retrieved = (intptr_t)k_timer_user_data_get(timer);
	user_data_correct[timer_num] = user_data[timer_num] == data_retrieved;
}

void test_timer_user_data(void)
{
	int ii;

	for (ii = 0; ii < 5; ii++) {
		intptr_t check;

		k_timer_user_data_set(user_data_timer[ii],
				      (void *)user_data[ii]);
		check = (intptr_t)k_timer_user_data_get(user_data_timer[ii]);

		zassert_true(check == user_data[ii], NULL);
	}

	for (ii = 0; ii < 5; ii++) {
		k_timer_start(user_data_timer[ii], 50 + ii * 50, 0);
	}

	k_sleep(50 * ii + 50);

	for (ii = 0; ii < 5; ii++) {
		k_timer_stop(user_data_timer[ii]);
	}

	for (ii = 0; ii < 5; ii++) {
		zassert_true(user_data_correct[ii], NULL);
	}
}
