#![cfg_attr(test, allow(unused))] // RT initialization logic is not compiled for test

use crate::io::Write;
use core::arch::global_asm;
use core::sync::atomic::{AtomicUsize, Ordering};

// runtime features
pub(super) mod panic;
mod reloc;

// library features
pub mod mem;
pub mod thread;
pub mod tls;
#[macro_use]
pub mod usercalls;

#[cfg(not(test))]
global_asm!(include_str!("entry.S"), options(att_syntax));

#[repr(C)]
struct EntryReturn(u64, u64);

#[cfg(not(test))]
#[no_mangle]
unsafe extern "C" fn tcs_init(secondary: bool) {
    // Be very careful when changing this code: it runs before the binary has been
    // relocated. Any indirect accesses to symbols will likely fail.
    const UNINIT: usize = 0;
    const BUSY: usize = 1;
    const DONE: usize = 2;
    // Three-state spin-lock
    static RELOC_STATE: AtomicUsize = AtomicUsize::new(UNINIT);

    if secondary && RELOC_STATE.load(Ordering::Relaxed) != DONE {
        rtabort!("Entered secondary TCS before main TCS!")
    }

    // Try to atomically swap UNINIT with BUSY. The returned state can be:
    match RELOC_STATE.compare_exchange(UNINIT, BUSY, Ordering::Acquire, Ordering::Acquire) {
        // This thread just obtained the lock and other threads will observe BUSY
        Ok(_) => {
            reloc::relocate_elf_rela();
            RELOC_STATE.store(DONE, Ordering::Release);
        }
        // We need to wait until the initialization is done.
        Err(BUSY) => {
            while RELOC_STATE.load(Ordering::Acquire) == BUSY {
                core::hint::spin_loop();
            }
        }
        // Initialization is done.
        Err(DONE) => {}
        _ => unreachable!(),
    }
}

// FIXME: this item should only exist if this is linked into an executable
// (main function exists). If this is a library, the crate author should be
// able to specify this
#[cfg(not(test))]
#[no_mangle]
extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> EntryReturn {
    // FIXME: how to support TLS in library mode?
    let tls = Box::new(tls::Tls::new());
    let tls_guard = unsafe { tls.activate() };

    if secondary {
        let join_notifier = super::thread::Thread::entry();
        drop(tls_guard);
        drop(join_notifier);

        EntryReturn(0, 0)
    } else {
        extern "C" {
            fn main(argc: isize, argv: *const *const u8) -> isize;
        }

        // check entry is being called according to ABI
        rtassert!(p3 == 0);
        rtassert!(p4 == 0);
        rtassert!(p5 == 0);

        unsafe {
            // The actual types of these arguments are `p1: *const Arg, p2:
            // usize`. We can't currently customize the argument list of Rust's
            // main function, so we pass these in as the standard pointer-sized
            // values in `argc` and `argv`.
            let ret = main(p2 as _, p1 as _);
            exit_with_code(ret)
        }
    }
}

pub(super) fn exit_with_code(code: isize) -> ! {
    if code != 0 {
        if let Some(mut out) = panic::SgxPanicOutput::new() {
            let _ = write!(out, "Exited with status code {code}");
        }
    }
    usercalls::exit(code != 0);
}

#[cfg(not(test))]
#[no_mangle]
extern "C" fn abort_reentry() -> ! {
    usercalls::exit(false)
}
