/*
 * Copyright (c) 2019-2020, Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <ztest.h>
#include <zephyr/drivers/entropy.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
#include <hal/nrf_clock.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(test);

#define TEST_TIME_MS 10000

#define HF_STARTUP_TIME_US 400

static bool test_end;

#include <hal/nrf_gpio.h>

static const struct device *entropy = DEVICE_DT_GET(DT_CHOSEN(zephyr_entropy));
static struct onoff_manager *hf_mgr;
static uint32_t iteration;

static void setup(void)
{
	zassert_true(device_is_ready(entropy), NULL);

	hf_mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
	zassert_true(hf_mgr, NULL);

	iteration = 0;
}

static void teardown(void)
{
	/* empty */
}

static void bt_timeout_handler(struct k_timer *timer)
{
	static bool on;

	nrf_gpio_cfg_output(27);
	if (on) {
		on = false;
		nrf_gpio_pin_clear(27);
		z_nrf_clock_bt_ctlr_hf_release();
	} else {
		nrf_gpio_pin_set(27);
		on = true;
		z_nrf_clock_bt_ctlr_hf_request();
	}

	if (!(test_end && !on)) {
		k_timeout_t timeout;
		static bool long_timeout;

		if (!on) {
			timeout = Z_TIMEOUT_US(200);
		} else {
			timeout = Z_TIMEOUT_US(long_timeout ? 300 : 100);
			long_timeout = !long_timeout;
		}
		k_timer_start(timer, timeout, K_NO_WAIT);
	}
}

K_TIMER_DEFINE(timer1, bt_timeout_handler, NULL);

static void check_hf_status(const struct device *dev, bool exp_on,
			    bool sw_check)
{
	nrf_clock_hfclk_t type;

	nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_HFCLK, &type);
	zassert_equal(type, exp_on ? NRF_CLOCK_HFCLK_HIGH_ACCURACY :
				NRF_CLOCK_HFCLK_LOW_ACCURACY,
			"%d: Clock expected to be %s",
			iteration, exp_on ? "on" : "off");

	if (sw_check) {
		enum clock_control_status status =
		     clock_control_get_status(dev, CLOCK_CONTROL_NRF_SUBSYS_HF);

		zassert_equal(status, exp_on ? CLOCK_CONTROL_STATUS_ON :
						CLOCK_CONTROL_STATUS_OFF,
				"%d: Unexpected status: %d", iteration, status);
	}

}

/* Test controls HF clock from two contexts: thread and timer interrupt.
 * In thread context clock is requested and released through standard onoff
 * API and in the timeout handler it is requested and released using API
 * dedicated to be used by Bluetooth Controller.
 *
 * Test runs in the loop to eventually lead to cases when clock controlling is
 * preempted by timeout handler. At certain points clock status is validated.
 */
static void test_onoff_interrupted(void)
{
	const struct device *clock_dev =
		device_get_binding(DT_LABEL(DT_INST(0, nordic_nrf_clock)));
	struct onoff_client cli;
	uint64_t start_time = k_uptime_get();
	uint64_t elapsed;
	uint64_t checkpoint = 1000;
	int err;
	uint8_t rand;
	int backoff;

	k_timer_start(&timer1, K_MSEC(1), K_NO_WAIT);

	while (1) {
		iteration++;

		err = entropy_get_entropy(entropy, &rand, 1);
		zassert_equal(err, 0, NULL);
		backoff = 3 * rand;

		sys_notify_init_spinwait(&cli.notify);
		err = onoff_request(hf_mgr, &cli);
		zassert_true(err >= 0, NULL);

		k_busy_wait(backoff);

		if (backoff > HF_STARTUP_TIME_US) {
			check_hf_status(clock_dev, true, true);
		}

		err = onoff_cancel_or_release(hf_mgr, &cli);
		zassert_true(err >= 0, NULL);

		elapsed = k_uptime_get() - start_time;
		if (elapsed > checkpoint) {
			printk("test continues\n");
			checkpoint += 1000;
		}

		if (elapsed > TEST_TIME_MS) {
			test_end = true;
			break;
		}
	}

	k_msleep(100);
	check_hf_status(clock_dev, false, true);
}

static void onoff_timeout_handler(struct k_timer *timer)
{
	static bool on;
	static struct onoff_client cli;
	static uint32_t cnt;
	int err;

	cnt++;
	if (on) {
		on = false;
		err = onoff_cancel_or_release(hf_mgr, &cli);
		zassert_true(err >= 0, NULL);
	} else {
		on = true;
		sys_notify_init_spinwait(&cli.notify);
		err = onoff_request(hf_mgr, &cli);
		zassert_true(err >= 0, "%d: Unexpected err: %d", cnt, err);
	}

	if (!(test_end && !on)) {
		k_timeout_t timeout;
		static bool long_timeout;

		if (!on) {
			timeout = Z_TIMEOUT_US(200);
		} else {
			timeout = Z_TIMEOUT_US(long_timeout ? 300 : 100);
			long_timeout = !long_timeout;
		}
		k_timer_start(timer, timeout, K_NO_WAIT);
	}
}

K_TIMER_DEFINE(timer2, onoff_timeout_handler, NULL);

/* Test controls HF clock from two contexts: thread and timer interrupt.
 * In thread context clock is requested and released through API
 * dedicated to be used by Bluetooth Controller and in the timeout handler it is
 * requested and released using standard onoffAPI .
 *
 * Test runs in the loop to eventually lead to cases when clock controlling is
 * preempted by timeout handler. At certain points clock status is validated.
 */
static void test_bt_interrupted(void)
{
	const struct device *clock_dev =
		device_get_binding(DT_LABEL(DT_INST(0, nordic_nrf_clock)));
	uint64_t start_time = k_uptime_get();
	uint64_t elapsed;
	uint64_t checkpoint = 1000;
	int err;
	uint8_t rand;
	int backoff;

	k_timer_start(&timer2, K_MSEC(1), K_NO_WAIT);

	while (1) {
		iteration++;

		err = entropy_get_entropy(entropy, &rand, 1);
		zassert_equal(err, 0, NULL);
		backoff = 3 * rand;

		z_nrf_clock_bt_ctlr_hf_request();

		k_busy_wait(backoff);

		if (backoff > HF_STARTUP_TIME_US) {
			check_hf_status(clock_dev, true, false);
		}

		z_nrf_clock_bt_ctlr_hf_release();

		elapsed = k_uptime_get() - start_time;
		if (elapsed > checkpoint) {
			printk("test continues\n");
			checkpoint += 1000;
		}

		if (elapsed > TEST_TIME_MS) {
			test_end = true;
			break;
		}
	}

	k_msleep(100);
	check_hf_status(clock_dev, false, true);
}

void test_main(void)
{
	ztest_test_suite(test_nrf_onoff_and_bt,
		ztest_unit_test_setup_teardown(test_onoff_interrupted,
					       setup, teardown),
		ztest_unit_test_setup_teardown(test_bt_interrupted,
					       setup, teardown)
			);
	ztest_run_test_suite(test_nrf_onoff_and_bt);
}
