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

static nrf_clock_lfclk_t type;
static bool on;
static uint32_t rtc_cnt;

static void xtal_check(bool on, nrf_clock_lfclk_t type)
{
	if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
		zassert_false(on, "Clock should be off");
	} else if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY)) {
		bool is_running =
			rtc_cnt || (on && (type == NRF_CLOCK_LFCLK_RC));

		zassert_true(is_running, "Clock should be on");
	} else {
		zassert_true(on, "Clock should be on");
		zassert_equal(type, NRF_CLOCK_LFCLK_Xtal, NULL);
	}
}

static void rc_check(bool on, nrf_clock_lfclk_t type)
{
	if (IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
		zassert_false(on, "Clock should be off");
	} else {
		zassert_true(on, "Clock should be on");
		zassert_equal(type, NRF_CLOCK_LFCLK_RC, NULL);
	}
}

static void synth_check(bool on, nrf_clock_lfclk_t type)
{
	#if !defined(CLOCK_LFCLKSRC_SRC_Synth) && \
	    !defined(CLOCK_LFCLKSRC_SRC_LFSYNT)
	#define NRF_CLOCK_LFCLK_Synth 0
	#endif

	if (!IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT)) {
		zassert_true(on, "Clock should be on");
		zassert_equal(type, NRF_CLOCK_LFCLK_Synth, NULL);
	}
}

void test_clock_check(void)
{
	bool xtal;

	xtal = IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL) |
		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_LOW_SWING) |
		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_FULL_SWING);

	if (xtal) {
		xtal_check(on, type);
	} else if (IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC)) {
		rc_check(on, type);
	} else {
		synth_check(on, type);
	}
}

void test_wait_in_thread(void)
{
	nrf_clock_lfclk_t t;
	bool o;

	if (!(IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) &&
		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL))) {
		return;
	}

	z_nrf_clock_control_lf_on(CLOCK_CONTROL_NRF_LF_START_AVAILABLE);
	o = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &t);
	zassert_false((t == NRF_CLOCK_LFCLK_Xtal) && o, NULL);
	k_busy_wait(35);
	zassert_true(k_cycle_get_32() > 0, NULL);

	z_nrf_clock_control_lf_on(CLOCK_CONTROL_NRF_LF_START_STABLE);
	o = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &t);
	zassert_true((t == NRF_CLOCK_LFCLK_Xtal) && o, NULL);
}

void test_main(void)
{
	/* Do clock state read as early as possible. When RC is already running
	 * and XTAL has been started then LFSRCSTAT register content might be
	 * not valid, in that case read system clock to check if it has
	 * progressed.
	 */
	on = nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_LFCLK, &type);
	k_busy_wait(100);
	rtc_cnt = k_cycle_get_32();

	 TC_PRINT("CLOCK_CONTROL_NRF_K32SRC=%s\n",
		IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC) ? "RC"
		: IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH) ? "SYNTH"
		: IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL) ? "XTAL"
		: "???");
	TC_PRINT("SYSTEM_CLOCK_NO_WAIT=%c\n",
		 IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) ? 'y' : 'n');
	TC_PRINT("SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY=%c\n",
		 IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY) ?
		 'y' : 'n');
	TC_PRINT("SYSTEM_CLOCK_WAIT_FOR_STABILITY=%c\n",
		 IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_STABILITY) ?
		 'y' : 'n');

	ztest_test_suite(test_nrf_lf_clock_start,
		ztest_unit_test(test_clock_check),
		ztest_unit_test(test_wait_in_thread)
			);
	ztest_run_test_suite(test_nrf_lf_clock_start);
}
