//! Key types to index the _MALLCTL NAMESPACE_.
//!
//! The [`Name`] and [`Mib`]/[`MibStr`] types are provided as safe indices into
//! the _MALLCTL NAMESPACE_. These are constructed from null-terminated strings
//! via the [`AsName`] trait. The [`Access`] trait provides provides safe access
//! into the `_MALLCTL NAMESPACE_`.
//!
//! # Example
//!
//! ```
//! #[global_allocator]
//! static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
//!
//! fn main() {
//!     use tikv_jemalloc_ctl::{Access, AsName, Name, Mib};
//!     use libc::{c_uint, c_char};
//!     let name = b"arenas.nbins\0".name();
//!     let nbins: c_uint = name.read().unwrap();
//!     let mut mib: Mib<[usize; 4]> = b"arenas.bin.0.size\0".name().mib().unwrap();
//!     for i in 0..4 {
//!         mib[2] = i;
//!         let bin_size: usize = mib.read().unwrap();
//!         println!("arena bin {} has size {}", i, bin_size);
//!     }
//! }
//! ```

#![allow(clippy::uninlined_format_args)]

use crate::error::Result;
use crate::std::str;
use crate::{fmt, ops, raw};

/// A `Name` in the _MALLCTL NAMESPACE_.
#[repr(transparent)]
#[derive(PartialEq, Eq)]
pub struct Name([u8]);

/// Converts a null-terminated byte-string into a [`Name`].
pub trait AsName {
    /// Converts a null-terminated byte-string into a [`Name`].
    fn name(&self) -> &Name;
}

impl AsName for [u8] {
    fn name(&self) -> &Name {
        assert!(
            !self.is_empty(),
            "cannot create Name from empty byte-string"
        );
        assert_eq!(
            *self.last().unwrap(),
            b'\0',
            "cannot create Name from non-null-terminated byte-string \"{}\"",
            str::from_utf8(self).unwrap()
        );
        unsafe { &*(self as *const Self as *const Name) }
    }
}

impl AsName for str {
    fn name(&self) -> &Name {
        self.as_bytes().name()
    }
}

impl Name {
    /// Returns the [`Mib`] of `self`.
    pub fn mib<T: MibArg>(&self) -> Result<Mib<T>> {
        let mut mib: Mib<T> = Mib::default();
        raw::name_to_mib(&self.0, mib.0.as_mut())?;
        Ok(mib)
    }

    /// Returns the [`MibStr`] of `self` which is a key whose value is a string.
    pub fn mib_str<T: MibArg>(&self) -> Result<MibStr<T>> {
        assert!(
            self.value_type_str(),
            "key \"{}\" does not refer to a string",
            self
        );
        let mut mib: MibStr<T> = MibStr::default();
        raw::name_to_mib(&self.0, mib.0.as_mut())?;
        Ok(mib)
    }

    /// Returns `true` if `self` is a key in the _MALLCTL NAMESPCE_ referring to
    /// a null-terminated string.
    pub fn value_type_str(&self) -> bool {
        // remove the null-terminator:
        let name = self.0.split_at(self.0.len() - 1).0;
        if name.is_empty() {
            return false;
        }
        debug_assert_ne!(*name.last().unwrap(), b'\0');

        match name {
            b"version"
            | b"config.malloc_conf"
            | b"opt.metadata_thp"
            | b"opt.dss"
            | b"opt.percpu_arena"
            | b"opt.stats_print_opts"
            | b"opt.junk"
            | b"opt.thp"
            | b"opt.prof_prefix"
            | b"thread.prof.name"
            | b"prof.dump" => true,
            v if v.starts_with(b"arena.") && v.ends_with(b".dss") => true,
            v if v.starts_with(b"stats.arenas.") && v.ends_with(b".dss") => {
                true
            }
            _ => false,
        }
    }

    /// Returns the name as null-terminated byte-string.
    pub fn as_bytes(&self) -> &'static [u8] {
        unsafe { &*(self as *const Self as *const [u8]) }
    }
}

impl fmt::Debug for Name {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", str::from_utf8(&self.0).unwrap())
    }
}

impl fmt::Display for Name {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", str::from_utf8(&self.0).unwrap())
    }
}

/// Management Information Base of a non-string value.
#[repr(transparent)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub struct Mib<T: MibArg>(T);

/// Management Information Base of a string value.
#[repr(transparent)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub struct MibStr<T: MibArg>(T);

impl<T: MibArg> AsRef<[usize]> for Mib<T> {
    fn as_ref(&self) -> &[usize] {
        self.0.as_ref()
    }
}

impl<T: MibArg> AsMut<[usize]> for Mib<T> {
    fn as_mut(&mut self) -> &mut [usize] {
        self.0.as_mut()
    }
}

impl<T: MibArg> ops::Index<usize> for Mib<T> {
    type Output = usize;
    fn index(&self, idx: usize) -> &Self::Output {
        &self.0.as_ref()[idx]
    }
}

impl<T: MibArg> ops::IndexMut<usize> for Mib<T> {
    fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
        &mut self.0.as_mut()[idx]
    }
}

impl<T: MibArg> ops::Index<usize> for MibStr<T> {
    type Output = usize;
    fn index(&self, idx: usize) -> &Self::Output {
        &self.0.as_ref()[idx]
    }
}

impl<T: MibArg> ops::IndexMut<usize> for MibStr<T> {
    fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
        &mut self.0.as_mut()[idx]
    }
}

/// Safe read access to the _MALLCTL NAMESPACE_.
pub trait Access<T> {
    /// Read the key at `self`.
    fn read(&self) -> Result<T>;
    /// Write `value` at the key `self`.
    fn write(&self, value: T) -> Result<()>;
    /// Write `value` at the key `self` returning its previous value.
    fn update(&self, value: T) -> Result<T>;
}

macro_rules! impl_access {
    ($id:ty) => {
        impl<T: MibArg> Access<$id> for Mib<T> {
            fn read(&self) -> Result<$id> {
                unsafe { raw::read_mib(self.0.as_ref()) }
            }
            fn write(&self, value: $id) -> Result<()> {
                unsafe { raw::write_mib(self.0.as_ref(), value) }
            }
            fn update(&self, value: $id) -> Result<$id> {
                unsafe { raw::update_mib(self.0.as_ref(), value) }
            }
        }
        impl Access<$id> for Name {
            fn read(&self) -> Result<$id> {
                unsafe { raw::read(&self.0) }
            }
            fn write(&self, value: $id) -> Result<()> {
                unsafe { raw::write(&self.0, value) }
            }
            fn update(&self, value: $id) -> Result<$id> {
                unsafe { raw::update(&self.0, value) }
            }
        }
    };
}

impl_access!(u32);
impl_access!(u64);
impl_access!(isize);
impl_access!(usize);

impl<T: MibArg> Access<bool> for Mib<T> {
    fn read(&self) -> Result<bool> {
        unsafe {
            let v: u8 = raw::read_mib(self.0.as_ref())?;
            assert!(v == 0 || v == 1);
            Ok(v == 1)
        }
    }
    fn write(&self, value: bool) -> Result<()> {
        unsafe { raw::write_mib(self.0.as_ref(), value) }
    }
    fn update(&self, value: bool) -> Result<bool> {
        unsafe {
            let v: u8 = raw::update_mib(self.0.as_ref(), value as u8)?;
            Ok(v == 1)
        }
    }
}

impl Access<bool> for Name {
    fn read(&self) -> Result<bool> {
        unsafe {
            let v: u8 = raw::read(&self.0)?;
            assert!(v == 0 || v == 1);
            Ok(v == 1)
        }
    }
    fn write(&self, value: bool) -> Result<()> {
        unsafe { raw::write(&self.0, value) }
    }
    fn update(&self, value: bool) -> Result<bool> {
        unsafe {
            let v: u8 = raw::update(&self.0, value as u8)?;
            Ok(v == 1)
        }
    }
}

impl<T: MibArg> Access<&'static [u8]> for MibStr<T> {
    fn read(&self) -> Result<&'static [u8]> {
        // this is safe because the only safe way to construct a `MibStr` is by
        // validating that the key refers to a byte-string value
        unsafe { raw::read_str_mib(self.0.as_ref()) }
    }
    fn write(&self, value: &'static [u8]) -> Result<()> {
        raw::write_str_mib(self.0.as_ref(), value)
    }
    fn update(&self, value: &'static [u8]) -> Result<&'static [u8]> {
        // this is safe because the only safe way to construct a `MibStr` is by
        // validating that the key refers to a byte-string value
        unsafe { raw::update_str_mib(self.0.as_ref(), value) }
    }
}

impl Access<&'static [u8]> for Name {
    fn read(&self) -> Result<&'static [u8]> {
        assert!(
            self.value_type_str(),
            "the name \"{:?}\" does not refer to a byte string",
            self
        );
        // this is safe because the key refers to a byte string:
        unsafe { raw::read_str(&self.0) }
    }
    fn write(&self, value: &'static [u8]) -> Result<()> {
        assert!(
            self.value_type_str(),
            "the name \"{:?}\" does not refer to a byte string",
            self
        );
        raw::write_str(&self.0, value)
    }
    fn update(&self, value: &'static [u8]) -> Result<&'static [u8]> {
        assert!(
            self.value_type_str(),
            "the name \"{:?}\" does not refer to a byte string",
            self
        );
        // this is safe because the key refers to a byte string:
        unsafe { raw::update_str(&self.0, value) }
    }
}

impl<T: MibArg> Access<&'static str> for MibStr<T> {
    fn read(&self) -> Result<&'static str> {
        // this is safe because the only safe way to construct a `MibStr` is by
        // validating that the key refers to a byte-string value
        let s = unsafe { raw::read_str_mib(self.0.as_ref())? };
        Ok(str::from_utf8(s).unwrap())
    }
    fn write(&self, value: &'static str) -> Result<()> {
        raw::write_str_mib(self.0.as_ref(), value.as_bytes())
    }
    fn update(&self, value: &'static str) -> Result<&'static str> {
        // this is safe because the only safe way to construct a `MibStr` is by
        // validating that the key refers to a byte-string value
        let s =
            unsafe { raw::update_str_mib(self.0.as_ref(), value.as_bytes())? };
        Ok(str::from_utf8(s).unwrap())
    }
}

impl Access<&'static str> for Name {
    fn read(&self) -> Result<&'static str> {
        assert!(
            self.value_type_str(),
            "the name \"{:?}\" does not refer to a byte string",
            self
        );
        // this is safe because the key refers to a byte string:
        let s = unsafe { raw::read_str(&self.0)? };
        Ok(str::from_utf8(s).unwrap())
    }
    fn write(&self, value: &'static str) -> Result<()> {
        assert!(
            self.value_type_str(),
            "the name \"{:?}\" does not refer to a byte string",
            self
        );
        raw::write_str(&self.0, value.as_bytes())
    }
    fn update(&self, value: &'static str) -> Result<&'static str> {
        assert!(
            self.value_type_str(),
            "the name \"{:?}\" does not refer to a byte string",
            self
        );
        // this is safe because the key refers to a byte string:
        let s = unsafe { raw::update_str(&self.0, value.as_bytes())? };
        Ok(str::from_utf8(s).unwrap())
    }
}

#[cfg(test)]
mod tests {
    use super::{Access, AsName, Mib, MibStr};
    #[test]
    fn bool_rw() {
        let name = b"thread.tcache.enabled\0".name();
        let tcache: bool = name.read().unwrap();

        let new_tcache = !tcache;

        name.write(new_tcache).unwrap();

        let mib: Mib<[usize; 3]> = name.mib().unwrap();
        let r: bool = mib.read().unwrap();
        assert_eq!(r, new_tcache);
    }

    #[test]
    fn u32_r() {
        let name = b"arenas.bin.0.nregs\0".name();
        let v: u32 = name.read().unwrap();

        let mib: Mib<[usize; 4]> = name.mib().unwrap();
        let r: u32 = mib.read().unwrap();
        assert_eq!(r, v);
    }

    #[test]
    fn size_t_r() {
        let name = b"arenas.lextent.0.size\0".name();
        let v: libc::size_t = name.read().unwrap();

        let mib: Mib<[usize; 4]> = name.mib().unwrap();
        let r: libc::size_t = mib.read().unwrap();
        assert_eq!(r, v);
    }

    #[test]
    fn ssize_t_rw() {
        let name = b"arenas.dirty_decay_ms\0".name();
        let v: libc::ssize_t = name.read().unwrap();
        name.write(v).unwrap();

        let mib: Mib<[usize; 2]> = name.mib().unwrap();
        let r: libc::ssize_t = mib.read().unwrap();
        assert_eq!(r, v);
    }

    #[test]
    fn u64_rw() {
        let name = b"epoch\0".name();
        let epoch: u64 = name.read().unwrap();
        name.write(epoch).unwrap();

        let mib: Mib<[usize; 1]> = name.mib().unwrap();
        let epoch: u64 = mib.read().unwrap();
        mib.write(epoch).unwrap();
    }

    #[test]
    fn str_rw() {
        let name = b"arena.0.dss\0".name();
        let dss: &'static [u8] = name.read().unwrap();
        name.write(dss).unwrap();

        let mib: MibStr<[usize; 3]> = name.mib_str().unwrap();
        let dss2: &'static [u8] = mib.read().unwrap();
        mib.write(dss2).unwrap();

        assert_eq!(dss, dss2);
    }
}

pub trait MibArg:
    Copy
    + Clone
    + PartialEq
    + Default
    + fmt::Debug
    + AsRef<[usize]>
    + AsMut<[usize]>
{
}
impl<T> MibArg for T where
    T: Copy
        + Clone
        + PartialEq
        + Default
        + fmt::Debug
        + AsRef<[usize]>
        + AsMut<[usize]>
{
}
