// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Type-safe bindings for Zircon threads.

use crate::{
    object_get_info_single, ok, sys, AsHandleRef, ExceptionReport, Handle, HandleBased, HandleRef,
    MonotonicDuration, ObjectQuery, Profile, Status, Task, Topic,
};
use bitflags::bitflags;

#[cfg(target_arch = "x86_64")]
use crate::{object_set_property, Property, PropertyQuery};

bitflags! {
    /// Options that may be used with `Thread::raise_exception`
    #[repr(transparent)]
    #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct RaiseExceptionOptions: u32 {
        const TARGET_JOB_DEBUGGER = sys::ZX_EXCEPTION_TARGET_JOB_DEBUGGER;
    }
}

/// An object representing a Zircon thread.
///
/// As essentially a subtype of `Handle`, it can be freely interconverted.
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct Thread(Handle);
impl_handle_based!(Thread);

struct ThreadExceptionReport;
unsafe impl ObjectQuery for ThreadExceptionReport {
    const TOPIC: Topic = Topic::THREAD_EXCEPTION_REPORT;
    type InfoTy = sys::zx_exception_report_t;
}

impl Thread {
    /// Cause the thread to begin execution.
    ///
    /// Wraps the
    /// [zx_thread_start](https://fuchsia.dev/fuchsia-src/reference/syscalls/thread_start.md)
    /// syscall.
    pub fn start(
        &self,
        thread_entry: usize,
        stack: usize,
        arg1: usize,
        arg2: usize,
    ) -> Result<(), Status> {
        let thread_raw = self.raw_handle();
        let status = unsafe { sys::zx_thread_start(thread_raw, thread_entry, stack, arg1, arg2) };
        ok(status)
    }

    /// Apply a scheduling profile to a thread.
    ///
    /// Wraps the
    /// [zx_object_set_profile](https://fuchsia.dev/fuchsia-src/reference/syscalls/object_set_profile) syscall.
    pub fn set_profile(&self, profile: Profile, options: u32) -> Result<(), Status> {
        let thread_raw = self.raw_handle();
        let profile_raw = profile.raw_handle();
        let status = unsafe { sys::zx_object_set_profile(thread_raw, profile_raw, options) };
        ok(status)
    }

    /// Terminate the current running thread.
    ///
    /// # Safety
    ///
    /// Extreme caution should be used-- this is basically always UB in Rust.
    /// There's almost no "normal" program code where this is okay to call.
    /// Users should take care that no references could possibly exist to
    /// stack variables on this thread, and that any destructors, closure
    /// suffixes, or other "after this thing runs" code is waiting to run
    /// in order for safety.
    pub unsafe fn exit() {
        sys::zx_thread_exit()
    }

    /// Wraps the
    /// [zx_object_get_info](https://fuchsia.dev/fuchsia-src/reference/syscalls/object_get_info.md)
    /// syscall for the ZX_INFO_THREAD_EXCEPTION_REPORT topic.
    pub fn get_exception_report(&self) -> Result<ExceptionReport, Status> {
        let raw = object_get_info_single::<ThreadExceptionReport>(self.as_handle_ref())?;

        // SAFETY: this value was provided by the kernel, the union is valid.
        Ok(unsafe { ExceptionReport::from_raw(raw) })
    }

    /// Wraps the
    /// [zx_object_get_info](https://fuchsia.dev/fuchsia-src/reference/syscalls/object_get_info.md)
    /// syscall for the ZX_INFO_THREAD topic.
    pub fn get_thread_info(&self) -> Result<ThreadInfo, Status> {
        Ok(ThreadInfo::from_raw(object_get_info_single::<ThreadInfoQuery>(self.as_handle_ref())?))
    }

    /// Wraps the
    /// [zx_object_get_info](https://fuchsia.dev/fuchsia-src/reference/syscalls/object_get_info.md)
    /// syscall for the ZX_INFO_THREAD_STATS topic.
    pub fn get_stats(&self) -> Result<ThreadStats, Status> {
        Ok(ThreadStats::from_raw(object_get_info_single::<ThreadStatsQuery>(self.as_handle_ref())?))
    }

    pub fn read_state_general_regs(&self) -> Result<sys::zx_thread_state_general_regs_t, Status> {
        let mut state = sys::zx_thread_state_general_regs_t::default();
        let thread_raw = self.raw_handle();
        let status = unsafe {
            sys::zx_thread_read_state(
                thread_raw,
                sys::ZX_THREAD_STATE_GENERAL_REGS,
                std::ptr::from_mut(&mut state).cast::<u8>(),
                std::mem::size_of_val(&state),
            )
        };
        ok(status).map(|_| state)
    }

    pub fn write_state_general_regs(
        &self,
        state: sys::zx_thread_state_general_regs_t,
    ) -> Result<(), Status> {
        let thread_raw = self.raw_handle();
        let status = unsafe {
            sys::zx_thread_write_state(
                thread_raw,
                sys::ZX_THREAD_STATE_GENERAL_REGS,
                std::ptr::from_ref(&state).cast::<u8>(),
                std::mem::size_of_val(&state),
            )
        };
        ok(status)
    }

    /// Wraps the `zx_thread_raise_exception` syscall.
    ///
    /// See https://fuchsia.dev/reference/syscalls/thread_raise_exception?hl=en for details.
    pub fn raise_user_exception(
        options: RaiseExceptionOptions,
        synth_code: u32,
        synth_data: u32,
    ) -> Result<(), Status> {
        let arch = unsafe { std::mem::zeroed::<sys::zx_exception_header_arch_t>() };
        let context = sys::zx_exception_context_t { arch, synth_code, synth_data };

        // SAFETY: basic FFI call. `&context` is a valid pointer.
        ok(unsafe { sys::zx_thread_raise_exception(options.bits(), sys::ZX_EXCP_USER, &context) })
    }
}

impl Task for Thread {}

struct ThreadStatsQuery;
unsafe impl ObjectQuery for ThreadStatsQuery {
    const TOPIC: Topic = Topic::THREAD_STATS;
    type InfoTy = sys::zx_info_thread_stats_t;
}

#[cfg(target_arch = "x86_64")]
unsafe_handle_properties!(object: Thread,
    props: [
        {query_ty: REGISTER_GS, tag: RegisterGsTag, prop_ty: usize, set: set_register_gs},
        {query_ty: REGISTER_FS, tag: RegisterFsTag, prop_ty: usize, set: set_register_fs},
    ]
);

#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
pub struct ThreadStats {
    pub total_runtime: MonotonicDuration,
    pub last_scheduled_cpu: u32,
}

impl ThreadStats {
    fn from_raw(
        sys::zx_info_thread_stats_t { total_runtime, last_scheduled_cpu }: sys::zx_info_thread_stats_t,
    ) -> Self {
        Self { total_runtime: MonotonicDuration::from_nanos(total_runtime), last_scheduled_cpu }
    }
}

struct ThreadInfoQuery;
unsafe impl ObjectQuery for ThreadInfoQuery {
    const TOPIC: Topic = Topic::THREAD;
    type InfoTy = sys::zx_info_thread_t;
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct ThreadInfo {
    pub state: ThreadState,
    pub cpu_affinity_mask: sys::zx_cpu_set_t,
}

impl ThreadInfo {
    fn from_raw(raw: sys::zx_info_thread_t) -> Self {
        Self {
            state: ThreadState::from_raw(raw.state, raw.wait_exception_channel_type),
            cpu_affinity_mask: raw.cpu_affinity_mask,
        }
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ThreadState {
    New,
    Running,
    Suspended,
    Blocked(ThreadBlockType),
    Dying,
    Dead,
    Unknown(u32),
}

impl ThreadState {
    fn from_raw(raw_state: u32, raw_wait_exception_channel_type: u32) -> Self {
        match raw_state {
            sys::ZX_THREAD_STATE_NEW => Self::New,
            sys::ZX_THREAD_STATE_RUNNING => Self::Running,
            sys::ZX_THREAD_STATE_SUSPENDED => Self::Suspended,
            sys::ZX_THREAD_STATE_BLOCKED => Self::Blocked(ThreadBlockType::Unknown),
            sys::ZX_THREAD_STATE_BLOCKED_EXCEPTION => Self::Blocked(ThreadBlockType::Exception(
                ExceptionChannelType::from_raw(raw_wait_exception_channel_type),
            )),
            sys::ZX_THREAD_STATE_BLOCKED_SLEEPING => Self::Blocked(ThreadBlockType::Sleeping),
            sys::ZX_THREAD_STATE_BLOCKED_FUTEX => Self::Blocked(ThreadBlockType::Futex),
            sys::ZX_THREAD_STATE_BLOCKED_PORT => Self::Blocked(ThreadBlockType::Port),
            sys::ZX_THREAD_STATE_BLOCKED_CHANNEL => Self::Blocked(ThreadBlockType::Channel),
            sys::ZX_THREAD_STATE_BLOCKED_WAIT_ONE => Self::Blocked(ThreadBlockType::WaitOne),
            sys::ZX_THREAD_STATE_BLOCKED_WAIT_MANY => Self::Blocked(ThreadBlockType::WaitMany),
            sys::ZX_THREAD_STATE_BLOCKED_INTERRUPT => Self::Blocked(ThreadBlockType::Interrupt),
            sys::ZX_THREAD_STATE_BLOCKED_PAGER => Self::Blocked(ThreadBlockType::Pager),
            sys::ZX_THREAD_STATE_DYING => Self::Dying,
            sys::ZX_THREAD_STATE_DEAD => Self::Dead,
            _ => Self::Unknown(raw_state),
        }
    }
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ThreadBlockType {
    Exception(ExceptionChannelType),
    Sleeping,
    Futex,
    Port,
    Channel,
    WaitOne,
    WaitMany,
    Interrupt,
    Pager,
    Unknown,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ExceptionChannelType {
    None,
    Debugger,
    Thread,
    Process,
    Job,
    JobDebugger,
    Unknown(u32),
}

impl ExceptionChannelType {
    fn from_raw(raw_wait_exception_channel_type: u32) -> Self {
        match raw_wait_exception_channel_type {
            sys::ZX_EXCEPTION_CHANNEL_TYPE_NONE => Self::None,
            sys::ZX_EXCEPTION_CHANNEL_TYPE_DEBUGGER => Self::Debugger,
            sys::ZX_EXCEPTION_CHANNEL_TYPE_THREAD => Self::Thread,
            sys::ZX_EXCEPTION_CHANNEL_TYPE_PROCESS => Self::Process,
            sys::ZX_EXCEPTION_CHANNEL_TYPE_JOB => Self::Job,
            sys::ZX_EXCEPTION_CHANNEL_TYPE_JOB_DEBUGGER => Self::JobDebugger,
            _ => Self::Unknown(raw_wait_exception_channel_type),
        }
    }
}

#[cfg(test)]
mod tests {
    use zx::{Handle, HandleBased, Profile, Status};

    #[test]
    fn set_profile_invalid() {
        let thread = fuchsia_runtime::with_thread_self(|thread| {
            thread.duplicate_handle(zx::Rights::SAME_RIGHTS).unwrap()
        });
        let profile = Profile::from(Handle::invalid());
        assert_eq!(thread.set_profile(profile, 0), Err(Status::BAD_HANDLE));
    }
}
