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

#include <zephyr/ztest.h>

#define ALIGN_MS_BOUNDARY		       \
	do {				       \
		uint32_t t = k_uptime_get_32();   \
		while (t == k_uptime_get_32()) \
			Z_SPIN_DELAY(50);      \
	} while (0)

struct timer_data {
	int duration_count;
	int stop_count;
};
static void duration_expire(struct k_timer *timer);
static void stop_expire(struct k_timer *timer);

/** TESTPOINT: init timer via K_TIMER_DEFINE */
K_TIMER_DEFINE(ktimer, duration_expire, stop_expire);

static ZTEST_BMEM struct timer_data tdata;

#define DURATION 100
#define LESS_DURATION 70

/**
 * @addtogroup kernel_common_tests
 * @{
 */

/**
 * @brief Test clock uptime APIs functionality
 *
 * @see k_uptime_get(), k_uptime_get_32(), k_uptime_delta()
 */
ZTEST_USER(clock, test_clock_uptime)
{
	uint64_t t64, t32;
	int64_t d64 = 0;

	/**TESTPOINT: uptime elapse*/
	t64 = k_uptime_get();
	while (k_uptime_get() < (t64 + 5)) {
		Z_SPIN_DELAY(50);
	}

	/**TESTPOINT: uptime elapse lower 32-bit*/
	t32 = k_uptime_get_32();
	while (k_uptime_get_32() < (t32 + 5)) {
		Z_SPIN_DELAY(50);
	}

	/**TESTPOINT: uptime straddled ms boundary*/
	t32 = k_uptime_get_32();
	ALIGN_MS_BOUNDARY;
	zassert_true(k_uptime_get_32() > t32);

	/**TESTPOINT: uptime delta*/
	d64 = k_uptime_delta(&d64);
	while (k_uptime_delta(&d64) == 0) {
		Z_SPIN_DELAY(50);
	}
}

/**
 * @brief Test 32-bit clock cycle functionality
 *
 * @details
 * Test Objective:
 * - The kernel architecture provide a 32bit monotonically increasing
 *   cycle counter
 * - This routine tests the k_cycle_get_32() and k_uptime_get_32()
 *   k_cycle_get_32() get cycles by accessing hardware clock.
 *   k_uptime_get_32() return cycles by transforming ticks into cycles.
 *
 * Testing techniques
 * - Functional and black box testing
 *
 * Prerequisite Condition:
 * - N/A
 *
 * Input Specifications:
 * - N/A
 *
 * Expected Test Result:
 * - The timer increases monotonically
 *
 * Pass/Fail criteria:
 * - Success if cycles increase monotonically, failure otherwise.
 *
 * Test Procedure:
 * -# At milli-second boundary, get cycles repeatedly by k_cycle_get_32()
 *  till cycles increased
 * -# At milli-second boundary, get cycles repeatedly by k_uptime_get_32()
 *  till cycles increased
 * -# Cross check cycles gotten by k_cycle_get_32() and k_uptime_get_32(),
 *  the delta cycle should be greater than 1 milli-second.
 *
 * Assumptions and Constraints
 * - N/A
 *
 * @see k_cycle_get_32(), k_uptime_get_32()
 */

ZTEST(clock, test_clock_cycle_32)
{
	uint32_t c32, c0, c1, t32;

	/**TESTPOINT: cycle elapse*/
	ALIGN_MS_BOUNDARY;
	c32 = k_cycle_get_32();
	/*break if cycle counter wrap around*/
	while (k_cycle_get_32() > c32 &&
	       k_cycle_get_32() < (c32 + k_ticks_to_cyc_floor32(1))) {
		Z_SPIN_DELAY(50);
	}

	/**TESTPOINT: cycle/uptime cross check*/
	c0 = k_cycle_get_32();
	ALIGN_MS_BOUNDARY;
	t32 = k_uptime_get_32();
	while (t32 == k_uptime_get_32()) {
		Z_SPIN_DELAY(50);
	}

	c1 = k_uptime_get_32();
	/*avoid cycle counter wrap around*/
	if (c1 > c0) {
		/* delta cycle should be greater than 1 milli-second*/
		zassert_true((c1 - c0) >
			     (sys_clock_hw_cycles_per_sec() / MSEC_PER_SEC),
			     NULL);
		/* delta NS should be greater than 1 milli-second */
		zassert_true((uint32_t)k_cyc_to_ns_floor64(c1 - c0) >
			     (NSEC_PER_SEC / MSEC_PER_SEC), NULL);
	}
}

/**
 * @brief Test 64-bit clock cycle functionality
 */
ZTEST(clock, test_clock_cycle_64)
{
	uint32_t d32;
	uint64_t d64;
	uint32_t t32[2];
	uint64_t t64[2];

	if (!IS_ENABLED(CONFIG_TIMER_HAS_64BIT_CYCLE_COUNTER)) {
		ztest_test_skip();
	}

	t64[0] = k_cycle_get_64();
	t32[0] = k_cycle_get_32();

	k_msleep(1);

	t32[1] = k_cycle_get_32();
	t64[1] = k_cycle_get_64();

	d32 = MIN(t32[1] - t32[0], t32[0] - t32[1]);
	d64 = MIN(t64[1] - t64[0], t64[1] - t64[0]);

	zassert_true(d64 >= d32,
		"k_cycle_get() (64-bit): d64: %" PRIu64 " < d32: %u", d64, d32);

	zassert_true(d64 < (d32 << 1),
		"k_cycle_get() (64-bit): d64: %" PRIu64 " >= 2 * d32: %u",
		d64, (d32 << 1));
}

/*
 *help function
 */
static void duration_expire(struct k_timer *timer)
{
	tdata.duration_count++;
}

static void stop_expire(struct k_timer *timer)
{
	tdata.stop_count++;
}

static void init_data_count(void)
{
	tdata.duration_count = 0;
	tdata.stop_count = 0;
}

/**
 * @brief Test millisecond time duration
 *
 * @details initialize a timer, then providing time duration in
 * millisecond, and check the duration time whether correct.
 *
 * @see k_timer_init(), k_timer_start(), k_timer_stop(),
 * k_busy_wait()
 *
 *
 */

ZTEST(clock, test_ms_time_duration)
{
	init_data_count();
	k_timer_start(&ktimer, K_MSEC(DURATION), K_NO_WAIT);

	/** TESTPOINT: waiting time less than duration and check the count*/
	k_busy_wait(LESS_DURATION * 1000);
	zassert_true(tdata.duration_count == 0);
	zassert_true(tdata.stop_count == 0);

	/** TESTPOINT: proving duration in millisecond */
	init_data_count();
	k_timer_start(&ktimer, K_MSEC(100), K_MSEC(50));

	/** TESTPOINT: waiting time more than duration and check the count */
	k_usleep(1);		/* align to tick */
	k_busy_wait((DURATION + 1) * 1000);
	zassert_true(tdata.duration_count == 1, "duration %u not 1",
		     tdata.duration_count);
	zassert_true(tdata.stop_count == 0,
		     "stop %u not 0", tdata.stop_count);

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

extern void *common_setup(void);
ZTEST_SUITE(clock, NULL, common_setup, NULL, NULL, NULL);

/**
 * @}
 */
