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

#pragma once

#include "common.h"
#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)
		};
		{
			T::next()
		} -> std::same_as<uint64_t>;
	};

	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
			{
				static constexpr uint64_t DistantFuture =
				  std::numeric_limits<uint64_t>::max();
				uint64_t nextTick  = threadHasNoPeers
				                       ? DistantFuture
				                       : time() + TIMERCYCLES_PER_TICK;
				uint64_t nextTimer = waitingListIsEmpty
				                       ? DistantFuture
				                       : Thread::waitingList->expiryTime;
				setnext(std::min(nextTick, nextTimer));
			}
		}

		/**
		 * Ensure that a timer tick is scheduled for the current thread.
		 */
		static void ensure_tick()
		{
			auto *thread = Thread::current_get();
			Debug::Assert(thread != nullptr,
			              "Ensure tick called with no running thread");
			auto tickTime = thread->expiryTime + TIMERCYCLES_PER_TICK;
			if (tickTime < TimerCore::next())
			{
				setnext(tickTime);
			}
		}

		/**
		 * 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(),
						           static_cast<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
