// Copyright 2019 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 Fuchsia-specific `libc` functionality.
//!
//! This crate is a minimal extension on top of the `fuchsia-zircon` crate,
//! which provides bindings to the Zircon kernel's syscalls, but does not
//! depend on functionality from `libc`.

// AKA `libc`-granted ambient-authority crate ;)

#![deny(missing_docs)]

use {
    fuchsia_zircon::{
        sys::{zx_handle_t, zx_status_t, ZX_HANDLE_INVALID}, // handle type (primitive, non-owning)
        Clock,
        Handle,
        HandleBased,
        Job,
        Process,
        Rights,
        Status,
        Thread,
        Time,
        Unowned,
        Vmar,
    },
    num_derive::FromPrimitive,
    num_traits::cast::FromPrimitive,
    std::convert::TryFrom,
    thiserror::Error,
};

// TODO(fxbug.dev/61174): Document these.
#[allow(missing_docs)]
extern "C" {
    pub fn zx_take_startup_handle(hnd_info: u32) -> zx_handle_t;
    pub fn zx_thread_self() -> zx_handle_t;
    pub fn zx_process_self() -> zx_handle_t;
    pub fn zx_vmar_root_self() -> zx_handle_t;
    pub fn zx_job_default() -> zx_handle_t;
    pub fn zx_utc_reference_get() -> zx_handle_t;
    pub fn zx_utc_reference_swap(
        new_handle: zx_handle_t,
        prev_handle: *mut zx_handle_t,
    ) -> zx_status_t;
}

/// Handle types as defined by the processargs protocol.
///
/// See [//zircon/system/public/zircon/processargs.h][processargs.h] for canonical definitions.
///
/// Short descriptions of each handle type are given, but more complete documentation may be found
/// in the [processargs.h] header.
///
/// [processargs.h]: https://fuchsia.googlesource.com/fuchsia/+/HEAD/zircon/system/public/zircon/processargs.h
#[repr(u8)]
#[derive(FromPrimitive, Copy, Clone, Debug, Eq, PartialEq)]
pub enum HandleType {
    /// Handle to our own process.
    ///
    /// Equivalent to PA_PROC_SELF.
    ProcessSelf = 0x01,

    /// Handle to the initial thread of our own process.
    ///
    /// Equivalent to PA_THREAD_SELF.
    ThreadSelf = 0x02,

    /// Handle to a job object which can be used to make child processes.
    ///
    /// The job can be the same as the one used to create this process or it can
    /// be different.
    ///
    /// Equivalent to PA_JOB_DEFAULT.
    DefaultJob = 0x03,

    /// Handle to the root of our address space.
    ///
    /// Equivalent to PA_VMAR_ROOT.
    RootVmar = 0x04,

    /// Handle to the VMAR used to load the initial program image.
    ///
    /// Equivalent to PA_VMAR_LOADED.
    LoadedVmar = 0x05,

    /// Service for loading shared libraries.
    ///
    /// See `fuchsia.ldsvc.Loader` for the interface definition.
    ///
    /// Equivalent to PA_LDSVC_LOADER.
    LdsvcLoader = 0x10,

    /// Handle to the VMO containing the vDSO ELF image.
    ///
    /// Equivalent to PA_VMO_VDSO.
    VdsoVmo = 0x11,

    /// Handle to the VMO used to map the initial thread's stack.
    ///
    /// Equivalent to PA_VMO_STACK.
    StackVmo = 0x13,

    /// Handle to the VMO for the main executable file.
    ///
    /// Equivalent to PA_VMO_EXECUTABLE.
    ExecutableVmo = 0x14,

    /// Used by kernel and userboot during startup.
    ///
    /// Equivalent to PA_VMO_BOOTDATA.
    BootdataVmo = 0x1A,

    /// Used by kernel and userboot during startup.
    ///
    /// Equivalent to PA_VMO_BOOTFS.
    BootfsVmo = 0x1B,

    /// Used by the kernel to export debug information as a file in bootfs.
    ///
    /// Equivalent to PA_VMO_KERNEL_FILE.
    KernelFileVmo = 0x1C,

    /// A handle to a fuchsia.io.Directory service to be used as a directory in the process's
    /// namespace. Corresponds to a path in the processargs bootstrap message's namespace table
    /// based on the argument of a HandleInfo of this type.
    ///
    /// Equivalent to PA_NS_DIR.
    NamespaceDirectory = 0x20,

    /// A handle which will be used as a file descriptor.
    ///
    /// Equivalent to PA_FD.
    FileDescriptor = 0x30,

    /// A Handle to a channel on which the process may serve the
    /// the |fuchsia.process.Lifecycle| protocol.
    ///
    /// Equivalent to PA_LIFECYCLE.
    Lifecycle = 0x3A,

    /// Server endpoint for handling connections to appmgr services.
    ///
    /// Equivalent to PA_DIRECTORY_REQUEST.
    DirectoryRequest = 0x3B,

    /// A Handle to a resource object. Used by devcoordinator and devhosts.
    ///
    /// Equivalent to PA_RESOURCE.
    Resource = 0x3F,

    /// A Handle to a clock object representing UTC.  Used by runtimes to gain
    /// access to UTC time.
    ///
    /// Equivalent to PA_CLOCK_UTC.
    ClockUtc = 0x40,

    /// A Handle to an MMIO resource object.
    ///
    /// Equivalent to PA_MMIO_RESOURCE.
    MmioResource = 0x50,

    /// A Handle to an IRQ resource object.
    ///
    /// Equivalent to PA_IRQ_RESOURCE.
    IrqResource = 0x51,

    /// A Handle to an IO Port resource object.
    ///
    /// Equivalent to PA_IOPORT_RESOURCE.
    IoportResource = 0x52,

    /// A Handle to an SMC resource object.
    ///
    /// Equivalent to PA_SMC_RESOURCE.
    SmcResource = 0x53,

    /// A Handle to the System resource object.
    ///
    /// Equivalent to PA_SYSTEM_RESOURCE.
    SystemResource = 0x54,

    /// A handle type with user-defined meaning.
    ///
    /// Equivalent to PA_USER0.
    User0 = 0xF0,

    /// A handle type with user-defined meaning.
    ///
    /// Equivalent to PA_USER1.
    User1 = 0xF1,

    /// A handle type with user-defined meaning.
    ///
    /// Equivalent to PA_USER2.
    User2 = 0xF2,

    #[doc(hidden)]
    __Nonexhaustive,
}

/// Metadata information for a handle in a processargs message. Contains a handle type and an
/// unsigned 16-bit value, whose meaning is handle type dependent.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct HandleInfo {
    htype: HandleType,
    arg: u16,
}

impl HandleInfo {
    /// Create a handle info struct from a handle type and an argument.
    ///
    /// For example, a `HandleInfo::new(HandleType::FileDescriptor, 32)` identifies
    /// the respective handle as file descriptor 32.
    ///
    /// Corresponds to PA_HND in processargs.h.
    pub fn new(htype: HandleType, arg: u16) -> Self {
        HandleInfo { htype, arg }
    }

    /// Returns the handle type for this handle info struct.
    pub fn handle_type(&self) -> HandleType {
        self.htype
    }

    /// Returns the argument for this handle info struct.
    pub fn arg(&self) -> u16 {
        self.arg
    }

    /// Convert the handle info into a raw u32 value for FFI purposes.
    pub fn as_raw(&self) -> u32 {
        ((self.htype as u32) & 0xFF) | (self.arg as u32) << 16
    }
}

/// An implementation of the From trait to create a [HandleInfo] from a [HandleType] with an argument
/// of 0.
impl From<HandleType> for HandleInfo {
    fn from(ty: HandleType) -> Self {
        Self::new(ty, 0)
    }
}

/// Possible errors when converting a raw u32 to a HandleInfo with the  TryFrom<u32> impl on
/// HandleInfo.
#[derive(Error, Debug)]
pub enum HandleInfoError {
    /// Unknown handle type.
    #[error("Unknown handle type for HandleInfo: {:#x?}", _0)]
    UnknownHandleType(u32),

    /// Otherwise invalid raw value, like reserved bytes being non-zero.
    #[error("Invalid value for HandleInfo: {:#x?}", _0)]
    InvalidHandleInfo(u32),
}

impl TryFrom<u32> for HandleInfo {
    type Error = HandleInfoError;

    /// Attempt to convert a u32 to a handle ID value. Can fail if the value represents an
    /// unknown handle type or is otherwise invalid.
    ///
    /// Useful to convert existing handle info values received through FIDL APIs, e.g. from a
    /// client that creates them using the PA_HND macro in processargs.h from C/C++.
    fn try_from(value: u32) -> Result<HandleInfo, HandleInfoError> {
        // 2nd byte should be zero, it is currently unused.
        if value & 0xFF00 != 0 {
            return Err(HandleInfoError::InvalidHandleInfo(value));
        }

        let htype = HandleType::from_u8((value & 0xFF) as u8)
            .ok_or(HandleInfoError::UnknownHandleType(value))?;
        Ok(HandleInfo::new(htype, (value >> 16) as u16))
    }
}

/// Removes the handle of type `HandleType` from the list of handles received at startup.
///
/// This function will return `Some` at-most once per handle type.
/// This function will return `None` if the requested type was not received at
/// startup or if the handle with the provided type was already taken.
pub fn take_startup_handle(info: HandleInfo) -> Option<Handle> {
    unsafe {
        let raw = zx_take_startup_handle(info.as_raw());
        if raw == ZX_HANDLE_INVALID {
            None
        } else {
            Some(Handle::from_raw(raw))
        }
    }
}

/// Get a reference to the handle of the current thread.
pub fn thread_self() -> Unowned<'static, Thread> {
    unsafe {
        let handle = zx_thread_self();
        Unowned::from_raw_handle(handle)
    }
}

/// Get a reference to the handle of the current process.
pub fn process_self() -> Unowned<'static, Process> {
    unsafe {
        let handle = zx_process_self();
        Unowned::from_raw_handle(handle)
    }
}

/// Get a reference to the handle of the current address space.
pub fn vmar_root_self() -> Unowned<'static, Vmar> {
    unsafe {
        let handle = zx_vmar_root_self();
        Unowned::from_raw_handle(handle)
    }
}

/// Get a reference to the default `Job` provided to the process on startup.
///
/// This typically refers to the `Job` that is the immediate parent of the current
/// process.
///
/// If the current process was launched as a Fuchsia Component, this `Job`
/// will begin with no child processes other than the current process.
pub fn job_default() -> Unowned<'static, Job> {
    unsafe {
        let handle = zx_job_default();
        Unowned::from_raw_handle(handle)
    }
}

/// Duplicate the UTC `Clock` registered with the runtime.
pub fn duplicate_utc_clock_handle(rights: Rights) -> Result<Clock, Status> {
    let handle: Unowned<'static, Clock> = unsafe {
        let handle = zx_utc_reference_get();
        Unowned::from_raw_handle(handle)
    };
    handle.duplicate(rights)
}

/// Swaps the current process-global UTC clock with `new_clock`, returning
/// the old clock on success.
/// If `new_clock` is a valid handle but does not have the ZX_RIGHT_READ right,
/// an error is returned and `new_clock` is dropped.
pub fn swap_utc_clock_handle(new_clock: Clock) -> Result<Clock, Status> {
    Ok(unsafe {
        let mut prev_handle = ZX_HANDLE_INVALID;
        Status::ok(zx_utc_reference_swap(new_clock.into_raw(), &mut prev_handle))?;
        Handle::from_raw(prev_handle)
    }
    .into())
}

/// Reads time from the UTC `Clock` registered with the runtime.
///
/// # Panics
///
/// Panics if there is no UTC clock registered with the runtime or the registered handle does not
/// have the required rights.
pub fn utc_time() -> Time {
    let clock: Unowned<'static, Clock> = unsafe {
        let handle = zx_utc_reference_get();
        Unowned::from_raw_handle(handle)
    };
    clock.read().expect("Failed to read UTC clock")
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn handle_id() {
        let mut randbuf = [0; 2];
        for type_val in 0..0xFF {
            if let Some(htype) = HandleType::from_u8(type_val as u8) {
                fuchsia_zircon::cprng_draw(&mut randbuf).unwrap();
                let arg = u16::from_le_bytes(randbuf);

                let info = HandleInfo::new(htype, arg);
                assert_eq!(info.handle_type(), htype);
                assert_eq!(info.arg(), arg);

                let info = HandleInfo::from(htype);
                assert_eq!(info.handle_type(), htype);
                assert_eq!(info.arg(), 0);
            }
        }
    }

    #[test]
    fn handle_id_raw() {
        assert_eq!(HandleInfo::new(HandleType::ProcessSelf, 0).as_raw(), 0x00000001);
        assert_eq!(HandleInfo::new(HandleType::DirectoryRequest, 0).as_raw(), 0x0000003B);
        assert_eq!(HandleInfo::new(HandleType::LdsvcLoader, 0xABCD).as_raw(), 0xABCD0010);
        assert_eq!(HandleInfo::new(HandleType::User0, 0x1).as_raw(), 0x000100F0);
        assert_eq!(HandleInfo::new(HandleType::User1, 0xABCD).as_raw(), 0xABCD00F1);
        assert_eq!(HandleInfo::new(HandleType::User2, 0xFFFF).as_raw(), 0xFFFF00F2);
    }

    #[test]
    fn handle_id_from_u32() {
        assert_eq!(
            HandleInfo::try_from(0x00000002).unwrap(),
            HandleInfo::new(HandleType::ThreadSelf, 0)
        );
        assert_eq!(
            HandleInfo::try_from(0x00040030).unwrap(),
            HandleInfo::new(HandleType::FileDescriptor, 4)
        );
        assert_eq!(
            HandleInfo::try_from(0x501C00F2).unwrap(),
            HandleInfo::new(HandleType::User2, 0x501C)
        );

        // Non-zero unused byte
        assert!(HandleInfo::try_from(0x00001100).is_err());
        assert!(HandleInfo::try_from(0x00010101).is_err());
        // Unknown handle type
        assert!(HandleInfo::try_from(0x00000000).is_err());
        assert!(HandleInfo::try_from(0x00000006).is_err());
    }

    #[test]
    fn read_utc_time() {
        utc_time();
    }
}
