use abi::{debug::TraceLevel, error::Error};
use libk::{
    debug,
    task::{thread::Thread, ThreadId},
};

pub(crate) fn debug_trace(level: TraceLevel, message: &str) {
    let thread = Thread::current();
    let process = thread.process();
    let level = match level {
        TraceLevel::Debug => log::Level::Debug,
        TraceLevel::Info => log::Level::Info,
        TraceLevel::Warn => log::Level::Warn,
        TraceLevel::Error => log::Level::Error,
    };

    debug::program_trace(&process, &thread, level, message);
}

pub(crate) fn debug_control(
    tid: u32,
    option: u32,
    buffer: &mut [u8],
    len: usize,
) -> Result<usize, Error> {
    let thread = Thread::current();
    let process = thread.process();
    let tid = ThreadId::User(tid as _);
    let tracee = Thread::get(tid).ok_or(Error::ProcessNotFound)?;

    if !tracee.is_tracee_of(process.id) {
        log::warn!("{}: {} is not our tracee", process.id, tracee.id);
        return Err(Error::PermissionDenied);
    }

    tracee.debug_control(option, buffer, len)
}
