// Copyright 2025 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#![no_std]

use pw_atomic::{AtomicBool, AtomicUsize};
use pw_log::info;
pub use time::{Duration, Instant};

pub mod interrupt_controller;
#[cfg(feature = "user_space")]
pub mod object;
#[cfg(not(feature = "std_panic_handler"))]
mod panic;
pub mod scheduler;
pub mod sync;
#[cfg(feature = "user_space")]
pub mod syscall;
pub use target::shutdown;
mod target;
mod trace;

use interrupt_controller::InterruptController;
use kernel_config::{KernelConfig, KernelConfigInterface};
#[cfg(feature = "user_space")]
pub use object::NullObjectTable;
#[doc(hidden)]
pub use scheduler::thread::{Process, Stack, StackStorage, StackStorageExt, Thread, ThreadState};
use scheduler::timer::TimerQueue;
use scheduler::{PreemptDisableGuard, SchedulerState, ThreadLocalState, thread};
pub use scheduler::{Priority, sleep_until, start_thread, yield_timeslice};
use sync::spinlock::{BareSpinLock, SpinLock, SpinLockGuard};
#[cfg(feature = "user_space")]
pub use syscall::SyscallArgs;

pub trait Arch: 'static + Copy + thread::ThreadArg {
    type ThreadState: ThreadState;
    type BareSpinLock: BareSpinLock;
    type Clock: time::Clock;
    type AtomicBool: AtomicBool;
    type AtomicUsize: AtomicUsize;
    #[cfg(feature = "user_space")]
    type SyscallArgs<'a>: SyscallArgs<'a>;
    type InterruptController: InterruptController;

    /// Switches to a new thread.
    ///
    /// - `sched_state`: A guard for the global `SchedulerState`
    ///   - This may be dropped and re-acquired across this function; the
    ///     returned guard is either still held or newly re-acquired
    /// - `old_thread_state`: The thread we're moving away from
    /// - `new_thread_state`: The thread we're moving to; must match
    ///   `current_thread` and the container for this `ThreadState`
    ///
    /// Returns:
    /// - `sched_state`: A guard for the global `SchedulerState`
    /// - `switched`: `true` if a context switch happened, `false` otherwise.
    ///
    /// If `switched` is `false`, the implementation guarantees that forward
    /// progress will be made. For example, a context switch may be deferred
    /// to an interrupt handler (like PendSV) which is pending. The caller
    /// does not need to retry or take further action to ensure the switch
    /// occurs.
    #[allow(clippy::missing_safety_doc)]
    unsafe fn context_switch(
        self,
        sched_state: SpinLockGuard<'_, Self, SchedulerState<Self>>,
        old_thread_state: *mut Self::ThreadState,
        new_thread_state: *mut Self::ThreadState,
    ) -> (SpinLockGuard<'_, Self, SchedulerState<Self>>, bool)
    where
        Self: Kernel;

    fn thread_local_state(self) -> &'static ThreadLocalState<Self>;

    fn now(self) -> Instant<Self::Clock>;

    fn get_interrupt_controller(self) -> &'static SpinLock<Self, Self::InterruptController>
    where
        Self: Kernel,
    {
        &self.get_state().arch_state.interrupt_controller
    }

    #[allow(dead_code)]
    fn idle(self) {}

    /// Early architecture initialization, called before the scheduler is bootstrapped.
    ///
    /// This is invoked during kernel startup before any threads exist and before
    /// the scheduler is operational. Architecture code **must not** call
    /// `scheduler::tick()` or any other scheduler functions during this phase.
    ///
    /// Use this for hardware initialization that must happen before the scheduler
    /// starts, such as setting up the interrupt controller or memory protection.
    fn early_init(self) {}

    /// Architecture initialization, called after the scheduler is bootstrapped.
    ///
    /// This is invoked after the scheduler is fully operational and threads can
    /// be scheduled. It is safe to call `scheduler::tick()` once `init()` is invoked.
    ///
    /// Use this for initialization that depends on the scheduler being ready,
    /// such as starting timer interrupts that will drive `scheduler::tick()`.
    ///
    /// # Contract
    ///
    /// - `early_init()` is always called before `init()`
    /// - `scheduler::tick()` **must not** be called by architecture code before
    ///   `init()` is invoked
    /// - Once `init()` is invoked, timer interrupts may safely call `scheduler::tick()`.
    ///   This includes interrupts that fire before `init()` returns. At this point,
    ///   only the bootstrap thread exists in the system and any context switch
    ///   requests will early exit, making this safe.
    fn init(self) {}

    fn panic() -> ! {
        #[allow(clippy::empty_loop)]
        loop {}
    }
}

pub struct ArchState<K: Kernel> {
    interrupt_controller: SpinLock<K, K::InterruptController>,
}

impl<K: Kernel> ArchState<K> {
    #[must_use]
    pub const fn new(interrupt_controller: K::InterruptController) -> Self {
        Self {
            interrupt_controller: SpinLock::new(interrupt_controller),
        }
    }
}

pub trait Kernel: Arch + Sync {
    fn get_state(self) -> &'static KernelState<Self>;

    fn get_scheduler(self) -> &'static SpinLock<Self, SchedulerState<Self>> {
        &self.get_state().scheduler
    }

    fn get_timer_queue(self) -> &'static SpinLock<Self, TimerQueue<Self>> {
        &self.get_state().timer_queue
    }
}

pub struct KernelState<K: Kernel> {
    arch_state: ArchState<K>,
    scheduler: SpinLock<K, SchedulerState<K>>,
    timer_queue: SpinLock<K, TimerQueue<K>>,

    // TODO: https://pwbug.dev/479857256 - Add configurable trace buffer size.
    #[cfg(feature = "tracing")]
    pub trace_buffer: pw_kernel_tracing::Buffer<K::AtomicUsize, 2048>,
}

impl<K: Kernel> KernelState<K> {
    #[must_use]
    pub const fn new(arch_state: ArchState<K>) -> Self {
        Self {
            arch_state,
            scheduler: SpinLock::new(SchedulerState::new()),
            timer_queue: SpinLock::new(TimerQueue::new()),
            #[cfg(feature = "tracing")]
            trace_buffer: pw_kernel_tracing::Buffer::new(),
        }
    }
}

#[cfg(not(feature = "tracing"))]
#[macro_export]
macro_rules! annotate_kernel_trace_buffer {
    ($trace_buffer:expr) => {{}};
}

#[cfg(feature = "tracing")]
#[macro_export]
macro_rules! annotate_kernel_trace_buffer {
    ($trace_buffer:expr) => {{
        #[repr(C, packed(1))]
        struct TraceBufferAnnotation {
            name: &'static str,
            addr: *const (),
            size: usize,
        }
        unsafe impl Sync for TraceBufferAnnotation {};

        #[unsafe(link_section = ".pw_kernel.annotations.trace_buffer")]
        #[used]
        static _TRACE_BUFFER_ANNOTATION: TraceBufferAnnotation = TraceBufferAnnotation {
            name: "kernel",
            addr: unsafe { $trace_buffer.buffer() },
            size: $trace_buffer.buffer_len(),
        };
    }};
}

#[macro_export]
macro_rules! annotate_kernel_state {
    ($state:expr) => {{ $crate::annotate_kernel_trace_buffer!($state.trace_buffer) }};
}

/// Initializes an [`InitKernelState`] in static storage.
///
/// # Examples
///
/// Here's an example of using `static_init_state!` on Cortex-M:
///
/// ```
/// struct Arch;
///
/// #[cortex_m_rt::entry]
/// fn main() -> ! {
///     Target::console_init();
///
///     kernel::static_init_state!(static mut INIT_STATE: InitKernelState<Arch>);
///
///     // SAFETY: `main` is only executed once, so we never generate more than one
///     // `&mut` reference to `INIT_STATE`.
///     kernel::Kernel::main(Arch, unsafe { &mut INIT_STATE });
/// }
/// ```
#[macro_export]
macro_rules! static_init_state {
    ($vis:vis static mut $name:ident: InitKernelState<$kernel:ty>) => {
        $vis static mut $name: $crate::InitKernelState<$kernel> = {
            use $crate::__private::kernel_config;
            use kernel_config::KernelConfigInterface as _;
            use kernel::StackStorageExt as _;
            use $crate::Priority;

            type Stack = $crate::StackStorage<{ kernel_config::KernelConfig::KERNEL_STACK_SIZE_BYTES }>;
            static mut BOOTSTRAP_STACK: Stack = Stack::ZEROED;
            static mut IDLE_STACK: Stack = Stack::ZEROED;

            $crate::annotate_stack!("bootstrap", &raw const BOOTSTRAP_STACK, kernel_config::KernelConfig::KERNEL_STACK_SIZE_BYTES);
            $crate::annotate_stack!("idle", &raw const IDLE_STACK, kernel_config::KernelConfig::KERNEL_STACK_SIZE_BYTES);

            $crate::InitKernelState {
                bootstrap_thread: $crate::ThreadStorage {
                    thread: $crate::Thread::new("bootstrap", Priority::DEFAULT_PRIORITY, $crate::Stack::new()),
                    // SAFETY: We're in a block used to initialize a `static`,
                    // which is only executed once.
                    stack: unsafe { &mut BOOTSTRAP_STACK },
                },
                idle_thread: $crate::ThreadStorage {
                    thread: $crate::Thread::new("idle", Priority::IDLE_PRIORITY, $crate::Stack::new()),
                    // SAFETY: We're in a block used to initialize a `static`,
                    // which is only executed once.
                    stack: unsafe { &mut IDLE_STACK},
                },
            }
        };

        // A null address is used as the ID of the kernel process for annotations
        // due to not being able to access the address of the kernel process
        // from here.
        $crate::annotate_thread_from_address!(
            "bootstrap",
            $kernel,
            &raw const $name.bootstrap_thread.thread,
            core::ptr::null());
        $crate::annotate_thread_from_address!(
            "idle",
            $kernel,
            &raw const $name.idle_thread.thread,
            core::ptr::null());
    };
}

#[doc(hidden)]
pub struct ThreadStorage<K: Kernel> {
    pub thread: Thread<K>,
    // We store the stack out of line so that it is treated as a separate
    // allocation from the containing `ThreadStorage`. The stack itself is
    // zero-initialized, while the `Thread` is not. If we include the stack in
    // the same allocation, then the entire allocation must be placed in the
    // binary itself (in `.data`). By contrast, if it is out of line, then the
    // fact that the whole stack is zero-initialized means that the linker can
    // put it in `.bss` and omit its contents from the binary entirely.
    //
    // See https://pwrev.dev/303372 (Ie93cfc52215753e1b4482d5fe3058dc53fcfa86a)
    // for more information.
    pub stack: &'static mut StackStorage<{ KernelConfig::KERNEL_STACK_SIZE_BYTES }>,
}

pub struct InitKernelState<K: Kernel> {
    #[doc(hidden)]
    pub bootstrap_thread: ThreadStorage<K>,
    #[doc(hidden)]
    pub idle_thread: ThreadStorage<K>,
}

// Module re-exporting modules into a scope that can be referenced by macros
// in this crate.
#[doc(hidden)]
pub mod macro_exports {
    pub use foreign_box;
    pub use pw_assert;
}

pub fn main<K: Kernel>(kernel: K, init_state: &'static mut InitKernelState<K>) -> ! {
    let preempt_guard = PreemptDisableGuard::new(kernel);

    kernel.get_interrupt_controller().lock(kernel).early_init();

    target::console_init();
    info!("Welcome to Maize on {}!", target::name() as &str);

    kernel.early_init();

    // Prepare the scheduler for thread initialization.
    scheduler::initialize(kernel);

    let bootstrap_thread = thread::init_thread_in(
        kernel,
        &mut init_state.bootstrap_thread.thread,
        init_state.bootstrap_thread.stack,
        "bootstrap",
        Priority::DEFAULT_PRIORITY,
        bootstrap_thread_entry,
        &mut init_state.idle_thread,
    );
    info!("Created initial thread; bootstrapping");

    // special case where we bootstrap the system by half context switching to this thread
    scheduler::bootstrap_scheduler(kernel, preempt_guard, bootstrap_thread);

    // never get to here
}

// completion of main in thread context
fn bootstrap_thread_entry<K: Kernel>(
    kernel: K,
    idle_thread_storage: &'static mut ThreadStorage<K>,
) {
    info!("Welcome to the first thread, continuing bootstrap");
    pw_assert::assert!(K::InterruptController::interrupts_enabled());

    kernel.init();

    let idle_thread = thread::init_thread_in(
        kernel,
        &mut idle_thread_storage.thread,
        idle_thread_storage.stack,
        "idle",
        Priority::IDLE_PRIORITY,
        idle_thread_entry,
        0,
    );

    scheduler::start_thread(kernel, idle_thread);

    target::main()
}

fn idle_thread_entry<K: Kernel>(kernel: K, _arg: usize) {
    // Fake idle thread to keep the runqueue from being empty if all threads are blocked.
    pw_assert::assert!(K::InterruptController::interrupts_enabled());
    loop {
        kernel.idle();
    }
}

/// Stores `t` in stack memory and provides a `&'static mut T` to a function
/// which will never return.
///
/// Since `F: FnOnce(...) -> !`, the stack memory holding `t` will never be
/// reclaimed, and so it can live forever (ie, be referenced using `&'static mut
/// T`).
///
/// If `f` unwinds, `with_static` will `loop {}` forever to prevent `t` from
/// being reclaimed.
pub fn with_static<T: 'static, F: FnOnce(&'static mut T)>(t: T, f: F) -> ! {
    struct LoopOnDrop<T>(T);
    impl<T> Drop for LoopOnDrop<T> {
        fn drop(&mut self) {
            #[allow(clippy::empty_loop)]
            loop {}
        }
    }

    let mut t = LoopOnDrop(t);
    let tp: *mut T = &mut t.0;

    // SAFETY: Since we `drop(t)` after the `loop {}`, `t` will only go out of
    // scope if `f` unwinds. If this happens, `LoopOnDrop::drop` will `loop {}`
    // forever before its inner `T` is destructed. Thus, `t.0` will never be
    // destructed, and so it is sound to synthesize a `'static` reference to
    // `t`.
    //
    // See for more analysis: https://github.com/rust-lang/unsafe-code-guidelines/issues/565
    f(unsafe { &mut *tp });

    #[allow(clippy::empty_loop)]
    loop {}
    #[allow(unreachable_code)]
    drop(t);
}

#[doc(hidden)]
pub mod __private {
    /// Takes a mutable reference to a global static.
    ///
    /// # Safety
    ///
    /// Each invocation of `static_mut_ref!` must be executed at most once at
    /// run time.
    #[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`
    #[macro_export]
    macro_rules! static_mut_ref {
        ($ty:ty = $value:expr) => {{
            use $crate::__private::foreign_box::StaticStorage;
            static mut __STATIC: StaticStorage<$ty> = StaticStorage::new();

            // Alias value to allow nested `unsafe` statements without warning.
            let value = $value;

            // SAFETY: The caller promises that this macro will be executed at
            // most once fulfilling `StaticStorage`'s precondition.
            unsafe { __STATIC.init(value) }
        }};
    }

    pub use foreign_box;
    pub use kernel_config;
    pub use time;
}
