// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT

#pragma once

#include "plic.h"
#include "thread.h"
#include <platform-timer.hh>
#include <stdint.h>
#include <tick_macros.h>
#include <utils.hh>

namespace
{
	/**
	 * Concept for the interface to setting the system timer.
	 */
	template<typename T>
	concept IsTimer = requires(uint32_t cycles)
	{
		{T::init()};
		{T::setnext(cycles)};
	};

	static_assert(
	  IsTimer<TimerCore>,
	  "Platform's timer implementation does not meet the required interface");

	/**
	 * Timer interface.  Provides generic timer functionality to the scheduler,
	 * wrapping the platform's timer device.
	 */
	class Timer final : private TimerCore
	{
		inline static uint64_t lastTickTime         = 0;
		inline static uint64_t zeroTickTime         = 0;
		inline static uint32_t accumulatedTickError = 0;

		public:
		/**
		 * Perform any setup necessary for the timer device.
		 */
		static void interrupt_setup()
		{
			static_assert(TIMERCYCLES_PER_TICK <= UINT32_MAX,
			              "Cycles per tick can't be represented in 32 bits. "
			              "Double check your platform config");
			init();
			zeroTickTime = time();
		}

		/**
		 * Expose the timer device's method for returning the current time.
		 */
		using TimerCore::time;

		/**
		 * Update the timer to fire the next timeout for the thread at the
		 * front of the queue, or disable the timer if there are no threads
		 * blocked with a timeout and no threads with the same priority.
		 *
		 * The scheduler is a simple RTOS scheduler that does not allow any
		 * thread to run if a higher-priority thread is runnable.  This means
		 * that we need a timer interrupt in one of two situations:
		 *
		 *  - We have a thread of the same priority as the current thread and
		 *    we are going to round-robin schedule it.
		 *  - We have a thread of a higher priority than the current thread
		 *    that is currently sleeping on a timeout and need it to preempt the
		 *    current thread when its timeout expires.
		 *
		 * We currently over approximate the second condition by making the
		 * timer fire independent of the priority.  If this is every changed,
		 * some care must be taken to ensure that dynamic priority propagation
		 * via priority-inheriting futexes behaves correctly.
		 *
		 * This should be called after scheduling has changed the list of
		 * waiting threads.
		 */
		static void update()
		{
			auto *thread             = Thread::current_get();
			bool  waitingListIsEmpty = ((Thread::waitingList == nullptr) ||
                                       (Thread::waitingList->expiryTime == -1));
			bool  threadHasNoPeers =
			  (thread == nullptr) || (!thread->has_priority_peers());
			if (waitingListIsEmpty && threadHasNoPeers)
			{
				clear();
			}
			else
			{
				uint64_t nextTimer = waitingListIsEmpty
				                       ? time() + TIMERCYCLES_PER_TICK
				                       : Thread::waitingList->expiryTime;
				setnext(nextTimer);
			}
		}

		/**
		 * Wake any threads that were sleeping until a timeout before the
		 * current time.  This also wakes yielded threads if there are no
		 * runnable threads.
		 *
		 * This should be called when a timer interrupt fires.
		 */
		static void expiretimers()
		{
			uint64_t now = time();
			Thread::ticksSinceBoot =
			  (now - zeroTickTime) / TIMERCYCLES_PER_TICK;
			if (Thread::waitingList == nullptr)
			{
				return;
			}
			for (Thread *iter = Thread::waitingList;;)
			{
				if (iter->expiryTime <= now)
				{
					Thread *iterNext = iter->timerNext;

					iter->ready(Thread::WakeReason::Timer);
					iter = iterNext;
					if (Thread::waitingList == nullptr ||
					    iter == Thread::waitingList)
					{
						break;
					}
				}
				else
				{
					break;
				}
			}
			// If there are not runnable threads, try to wake a yielded thread
			if (!Thread::any_ready())
			{
				// Look at the first thread.  If it is not yielding, there may
				// be another thread behind it that is, but that's fine.  We
				// don't want to encounter situations where (with a
				// high-priority A and a low-priority B):
				//
				// 1. A yields for 5 ticks.
				// 2. B starts and does a blocking operation (e.g. try_lock)
				//    with a 1-tick timeout.
				// 3. A wakes up and prevents B from running even though we're
				//    still in its 5-tick yield period.
				if (Thread *head = Thread::waitingList)
				{
					if (head->is_yielding())
					{
						Debug::log("Woke thread {} {} cycles early",
						           head->id_get(),
						           int64_t(head->expiryTime) - now);
						head->ready(Thread::WakeReason::Timer);
					}
				}
			}
		}
	};

	uint64_t expiry_time_for_timeout(uint32_t timeout)
	{
		if (timeout == -1)
		{
			return -1;
		}
		return Timer::time() + (timeout * TIMERCYCLES_PER_TICK);
	}
} // namespace
