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

#include <zephyr.h>
#include <ztest.h>
#include <kernel.h>
#include <pm/pm.h>
#include <pm/device_runtime.h>
#include "dummy_driver.h"

#define MAX_TIMES 10
#define STACKSIZE 1024

/* Semaphore used to synchronize thread A and thread B*/
K_SEM_DEFINE(sem, 0, 1);

K_THREAD_STACK_DEFINE(threadA_stack, STACKSIZE);
K_THREAD_STACK_DEFINE(threadB_stack, STACKSIZE);

static const struct device *dev;
static struct dummy_driver_api *api;

static struct k_thread threadA;
static struct k_thread threadB;


void threadA_func(void *arg1, void *arg2, void *arg3)
{
	int ret;

	ARG_UNUSED(arg1);
	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	ret = api->open(dev);
	zassert_true(ret == 0, "Fail to get device");

	/* Lets allow threadB run */
	k_sem_give(&sem);

	/* Block waiting for device operation conclude */
	ret = api->wait(dev);
	zassert_true(ret == 0, "Fail to wait transaction");

	/* At this point threadB should have put the device and
	 * the current state should be SUSPENDED.
	 */
	zassert_true(dev->pm->state == PM_DEVICE_STATE_SUSPENDED, "Wrong state");

	k_sem_take(&sem, K_FOREVER);

	ret = api->open(dev);
	zassert_true(ret == 0, "Fail to get device");

	/* Lets allow threadB run */
	k_sem_give(&sem);

	ret = api->wait(dev);
	zassert_true(ret == 0, "Fail to wait transaction");

	zassert_true(dev->pm->state == PM_DEVICE_STATE_ACTIVE, "Wrong state");
}

void threadB_func(void *arg1, void *arg2, void *arg3)
{
	int ret;

	ARG_UNUSED(arg1);
	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	k_sem_take(&sem, K_FOREVER);

	api->close(dev);

	k_sem_give(&sem);
	ret = api->wait(dev);
	zassert_true(ret == 0, "Fail to wait transaction");

	/* Check the state */
	zassert_true(dev->pm->state == PM_DEVICE_STATE_SUSPENDED, "Wrong state");
}

/*
 * @brief test device runtime concurrency
 *
 * @details
 *  - Two threads will do different operations on a device. ThreadA will
 *    try to bring up the device using an async call and then will be scheduled
 *    out and threadB will run. ThreadB then will suspend the device and give up
 *    in favor of threadA. At this point the device should reflect these
 *    operations and be suspended.
 *
 * @see pm_device_get_async(), pm_device_put_async()
 *
 * @ingroup power_tests
 */
void test_concurrency(void)
{
	k_thread_start(&threadA);
	k_thread_start(&threadB);

	k_thread_join(&threadA, K_FOREVER);
	k_thread_join(&threadB, K_FOREVER);
}

void test_setup(void)
{
	dev = device_get_binding(DUMMY_DRIVER_NAME);
	api = (struct dummy_driver_api *)dev->api;

	k_thread_create(&threadA, threadA_stack,
			K_THREAD_STACK_SIZEOF(threadA_stack),
			threadA_func, NULL, NULL, NULL,
			K_PRIO_PREEMPT(1), 0, K_FOREVER);

	/* Lets make threadB has higher priority than the workqueue
	 * used on device_runtime
	 */
	k_thread_create(&threadB, threadB_stack,
			K_THREAD_STACK_SIZEOF(threadB_stack),
			threadB_func, NULL, NULL, NULL,
			K_HIGHEST_THREAD_PRIO, 0, K_FOREVER);
}

void test_teardown(void)
{
	int ret;

	zassert_true(dev->pm->state == PM_DEVICE_STATE_ACTIVE, "Wrong state");

	ret = api->close_sync(dev);
	zassert_true(ret == 0, "Fail to suspend device");

	zassert_true(dev->pm->state == PM_DEVICE_STATE_SUSPENDED, "Wrong state");
}

/*
 * @brief test device runtime sync API
 *
 * @details
 *  - Just bring up and put down the device using the synchronous API.
 *
 * @see pm_device_get_async(), pm_device_put()
 *
 * @ingroup power_tests
 */
void test_sync(void)
{
	int ret;

	ret = api->open_sync(dev);
	zassert_true(ret == 0, "Fail to bring up device");

	zassert_true(dev->pm->state == PM_DEVICE_STATE_ACTIVE, "Wrong state");


	ret = api->close_sync(dev);
	zassert_true(ret == 0, "Fail to suspend device");

	zassert_true(dev->pm->state == PM_DEVICE_STATE_SUSPENDED, "Wrong state");
}

/*
 * @brief test device runtime async API with multiple calls to check
 * if the reference count keeps consistent.
 *
 * @ingroup power_tests
 */
void test_multiple_times(void)
{
	int ret;
	uint8_t i;

	/* First do it synchronously */
	for (i = 0; i < MAX_TIMES; i++) {
		ret = api->open_sync(dev);
		zassert_true(ret == 0, "Fail to bring up device");

		zassert_true(dev->pm->state == PM_DEVICE_STATE_ACTIVE, "Wrong state");


		ret = api->close_sync(dev);
		zassert_true(ret == 0, "Fail to suspend device");

		zassert_true(dev->pm->state == PM_DEVICE_STATE_SUSPENDED, "Wrong state");
	}

	/* Now do all requests for get and then all for put*/
	for (i = 0; i < MAX_TIMES; i++) {
		ret = api->open(dev);
		zassert_true(ret == 0, "Fail to bring up device");
	}

	for (i = 0; i < MAX_TIMES; i++) {
		ret = api->close(dev);
		zassert_true(ret == 0, "Fail to suspend device");
	}

	ret = api->wait(dev);
	zassert_true(ret == 0, "Fail to wait transaction");

	/* Check the state */
	zassert_true(dev->pm->state == PM_DEVICE_STATE_SUSPENDED, "Wrong state");

	/* Finally off by one to keep the device active*/
	for (i = 0; i < MAX_TIMES; i++) {
		ret = api->open(dev);
		zassert_true(ret == 0, "Fail to bring up device");
	}

	for (i = 0; i < MAX_TIMES - 1; i++) {
		ret = api->close(dev);
		zassert_true(ret == 0, "Fail to suspend device");
	}

	ret = api->wait(dev);
	zassert_true(ret == 0, "Fail to wait transaction");

	/* Check the state */
	zassert_true(dev->pm->state == PM_DEVICE_STATE_ACTIVE, "Wrong state");

}

void test_main(void)
{
	ztest_test_suite(device_runtime_test,
			 ztest_unit_test_setup_teardown(test_concurrency,
							test_setup,
							test_teardown),
			 ztest_unit_test(test_sync),
			 ztest_unit_test(test_multiple_times));
	ztest_run_test_suite(device_runtime_test);
}
