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

//! Provides infrastructure for de/serializing descriptors embedded in Rust data structures.
//!
//! # Example
//!
//! ```
//! use serde_json::to_string;
//! use base::{
//!     FileSerdeWrapper, FromRawDescriptor, SafeDescriptor, SerializeDescriptors,
//!     deserialize_with_descriptors,
//! };
//! use tempfile::tempfile;
//!
//! let tmp_f = tempfile().unwrap();
//!
//! // Uses a simple wrapper to serialize a File because we can't implement Serialize for File.
//! let data = FileSerdeWrapper(tmp_f);
//!
//! // Wraps Serialize types to collect side channel descriptors as Serialize is called.
//! let data_wrapper = SerializeDescriptors::new(&data);
//!
//! // Use the wrapper with any serializer to serialize data is normal, grabbing descriptors
//! // as the data structures are serialized by the serializer.
//! let out_json = serde_json::to_string(&data_wrapper).expect("failed to serialize");
//!
//! // If data_wrapper contains any side channel descriptor refs
//! // (it contains tmp_f in this case), we can retrieve the actual descriptors
//! // from the side channel using into_descriptors().
//! let out_descriptors = data_wrapper.into_descriptors();
//!
//! // When sending out_json over some transport, also send out_descriptors.
//!
//! // For this example, we aren't really transporting data across the process, but we do need to
//! // convert the descriptor type.
//! let mut safe_descriptors = out_descriptors
//!     .iter()
//!     .map(|&v| Some(unsafe { SafeDescriptor::from_raw_descriptor(v) }))
//!     .collect();
//! std::mem::forget(data); // Prevent double drop of tmp_f.
//!
//! // The deserialize_with_descriptors function is used give the descriptor deserializers access
//! // to side channel descriptors.
//! let res: FileSerdeWrapper =
//!     deserialize_with_descriptors(|| serde_json::from_str(&out_json), &mut safe_descriptors)
//!        .expect("failed to deserialize");
//! ```

use std::{
    cell::{Cell, RefCell},
    convert::TryInto,
    fmt,
    fs::File,
    ops::{Deref, DerefMut},
    panic::{catch_unwind, resume_unwind, AssertUnwindSafe},
};

use serde::{
    de::{
        Error, Visitor, {self},
    },
    ser, Deserialize, Deserializer, Serialize, Serializer,
};

use super::RawDescriptor;
use crate::descriptor::SafeDescriptor;

thread_local! {
    static DESCRIPTOR_DST: RefCell<Option<Vec<RawDescriptor>>> = Default::default();
}

/// Initializes the thread local storage for descriptor serialization. Fails if it was already
/// initialized without an intervening `take_descriptor_dst` on this thread.
fn init_descriptor_dst() -> Result<(), &'static str> {
    DESCRIPTOR_DST.with(|d| {
        let mut descriptors = d.borrow_mut();
        if descriptors.is_some() {
            return Err(
                "attempt to initialize descriptor destination that was already initialized",
            );
        }
        *descriptors = Some(Default::default());
        Ok(())
    })
}

/// Takes the thread local storage for descriptor serialization. Fails if there wasn't a prior call
/// to `init_descriptor_dst` on this thread.
fn take_descriptor_dst() -> Result<Vec<RawDescriptor>, &'static str> {
    match DESCRIPTOR_DST.with(|d| d.replace(None)) {
        Some(d) => Ok(d),
        None => Err("attempt to take descriptor destination before it was initialized"),
    }
}

/// Pushes a descriptor on the thread local destination of descriptors, returning the index in which
/// the descriptor was pushed.
//
/// Returns Err if the thread local destination was not already initialized.
fn push_descriptor(rd: RawDescriptor) -> Result<usize, &'static str> {
    DESCRIPTOR_DST.with(|d| {
        d.borrow_mut()
            .as_mut()
            .ok_or("attempt to serialize descriptor without descriptor destination")
            .map(|descriptors| {
                let index = descriptors.len();
                descriptors.push(rd);
                index
            })
    })
}

/// Serializes a descriptor for later retrieval in a parent `SerializeDescriptors` struct.
///
/// If there is no parent `SerializeDescriptors` being serialized, this will return an error.
///
/// For convenience, it is recommended to use the `with_raw_descriptor` module in a `#[serde(with =
/// "...")]` attribute which will make use of this function.
pub fn serialize_descriptor<S: Serializer>(
    rd: &RawDescriptor,
    se: S,
) -> std::result::Result<S::Ok, S::Error> {
    let index = push_descriptor(*rd).map_err(ser::Error::custom)?;
    se.serialize_u32(
        index
            .try_into()
            .map_err(|_| ser::Error::custom("attempt to serialize too many descriptors at once"))?,
    )
}

/// Wrapper for a `Serialize` value which will capture any descriptors exported by the value when
/// given to an ordinary `Serializer`.
///
/// This is the corresponding type to use for serialization before using
/// `deserialize_with_descriptors`.
///
/// # Examples
///
/// ```
/// use serde_json::to_string;
/// use base::platform::{FileSerdeWrapper, SerializeDescriptors};
/// use tempfile::tempfile;
///
/// let tmp_f = tempfile().unwrap();
/// let data = FileSerdeWrapper(tmp_f);
/// let data_wrapper = SerializeDescriptors::new(&data);
///
/// // Serializes `v` as normal...
/// let out_json = serde_json::to_string(&data_wrapper).expect("failed to serialize");
/// // If `serialize_descriptor` was called, we can capture the descriptors from here.
/// let out_descriptors = data_wrapper.into_descriptors();
/// ```
pub struct SerializeDescriptors<'a, T: Serialize>(&'a T, Cell<Vec<RawDescriptor>>);

impl<'a, T: Serialize> SerializeDescriptors<'a, T> {
    pub fn new(inner: &'a T) -> Self {
        Self(inner, Default::default())
    }

    pub fn into_descriptors(self) -> Vec<RawDescriptor> {
        self.1.into_inner()
    }
}

impl<'a, T: Serialize> Serialize for SerializeDescriptors<'a, T> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        init_descriptor_dst().map_err(ser::Error::custom)?;

        // catch_unwind is used to ensure that init_descriptor_dst is always balanced with a call to
        // take_descriptor_dst afterwards.
        let res = catch_unwind(AssertUnwindSafe(|| self.0.serialize(serializer)));
        self.1.set(take_descriptor_dst().unwrap());
        match res {
            Ok(r) => r,
            Err(e) => resume_unwind(e),
        }
    }
}

thread_local! {
    static DESCRIPTOR_SRC: RefCell<Option<Vec<Option<SafeDescriptor>>>> = Default::default();
}

/// Sets the thread local storage of descriptors for deserialization. Fails if this was already
/// called without a call to `take_descriptor_src` on this thread.
///
/// This is given as a collection of `Option` so that unused descriptors can be returned.
fn set_descriptor_src(descriptors: Vec<Option<SafeDescriptor>>) -> Result<(), &'static str> {
    DESCRIPTOR_SRC.with(|d| {
        let mut src = d.borrow_mut();
        if src.is_some() {
            return Err("attempt to set descriptor source that was already set");
        }
        *src = Some(descriptors);
        Ok(())
    })
}

/// Takes the thread local storage of descriptors for deserialization. Fails if the storage was
/// already taken or never set with `set_descriptor_src`.
///
/// If deserialization was done, the descriptors will mostly come back as `None` unless some of them
/// were unused.
fn take_descriptor_src() -> Result<Vec<Option<SafeDescriptor>>, &'static str> {
    DESCRIPTOR_SRC.with(|d| {
        d.replace(None)
            .ok_or("attempt to take descriptor source which was never set")
    })
}

/// Takes a descriptor at the given index from the thread local source of descriptors.
//
/// Returns None if the thread local source was not already initialized.
fn take_descriptor(index: usize) -> Result<SafeDescriptor, &'static str> {
    DESCRIPTOR_SRC.with(|d| {
        d.borrow_mut()
            .as_mut()
            .ok_or("attempt to deserialize descriptor without descriptor source")?
            .get_mut(index)
            .ok_or("attempt to deserialize out of bounds descriptor")?
            .take()
            .ok_or("attempt to deserialize descriptor that was already taken")
    })
}

/// Deserializes a descriptor provided via `deserialize_with_descriptors`.
///
/// If `deserialize_with_descriptors` is not in the call chain, this will return an error.
///
/// For convenience, it is recommended to use the `with_raw_descriptor` module in a `#[serde(with =
/// "...")]` attribute which will make use of this function.
pub fn deserialize_descriptor<'de, D>(de: D) -> std::result::Result<SafeDescriptor, D::Error>
where
    D: Deserializer<'de>,
{
    struct DescriptorVisitor;

    impl<'de> Visitor<'de> for DescriptorVisitor {
        type Value = u32;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("an integer which fits into a u32")
        }

        fn visit_u8<E: de::Error>(self, value: u8) -> Result<Self::Value, E> {
            Ok(value as _)
        }

        fn visit_u16<E: de::Error>(self, value: u16) -> Result<Self::Value, E> {
            Ok(value as _)
        }

        fn visit_u32<E: de::Error>(self, value: u32) -> Result<Self::Value, E> {
            Ok(value)
        }

        fn visit_u64<E: de::Error>(self, value: u64) -> Result<Self::Value, E> {
            value.try_into().map_err(E::custom)
        }

        fn visit_u128<E: de::Error>(self, value: u128) -> Result<Self::Value, E> {
            value.try_into().map_err(E::custom)
        }

        fn visit_i8<E: de::Error>(self, value: i8) -> Result<Self::Value, E> {
            value.try_into().map_err(E::custom)
        }

        fn visit_i16<E: de::Error>(self, value: i16) -> Result<Self::Value, E> {
            value.try_into().map_err(E::custom)
        }

        fn visit_i32<E: de::Error>(self, value: i32) -> Result<Self::Value, E> {
            value.try_into().map_err(E::custom)
        }

        fn visit_i64<E: de::Error>(self, value: i64) -> Result<Self::Value, E> {
            value.try_into().map_err(E::custom)
        }

        fn visit_i128<E: de::Error>(self, value: i128) -> Result<Self::Value, E> {
            value.try_into().map_err(E::custom)
        }
    }

    let index = de.deserialize_u32(DescriptorVisitor)? as usize;
    take_descriptor(index).map_err(D::Error::custom)
}

/// Allows the use of any serde deserializer within a closure while providing access to the a set of
/// descriptors for use in `deserialize_descriptor`.
///
/// This is the corresponding call to use deserialize after using `SerializeDescriptors`.
///
/// If `deserialize_with_descriptors` is called anywhere within the given closure, it return an
/// error.
pub fn deserialize_with_descriptors<F, T, E>(
    f: F,
    descriptors: &mut Vec<Option<SafeDescriptor>>,
) -> Result<T, E>
where
    F: FnOnce() -> Result<T, E>,
    E: de::Error,
{
    let swap_descriptors = std::mem::take(descriptors);
    set_descriptor_src(swap_descriptors).map_err(E::custom)?;

    // catch_unwind is used to ensure that set_descriptor_src is always balanced with a call to
    // take_descriptor_src afterwards.
    let res = catch_unwind(AssertUnwindSafe(f));

    // unwrap is used because set_descriptor_src is always called before this, so it should never
    // panic.
    *descriptors = take_descriptor_src().unwrap();

    match res {
        Ok(r) => r,
        Err(e) => resume_unwind(e),
    }
}

/// Module that exports `serialize`/`deserialize` functions for use with `#[serde(with = "...")]`
/// attribute. It only works with fields with `RawDescriptor` type.
///
/// # Examples
///
/// ```
/// use serde::{Deserialize, Serialize};
/// use base::platform::RawDescriptor;
///
/// #[derive(Serialize, Deserialize)]
/// struct RawContainer {
///     #[serde(with = "base::platform::with_raw_descriptor")]
///     rd: RawDescriptor,
/// }
/// ```
pub mod with_raw_descriptor {
    use super::super::RawDescriptor;
    use crate::descriptor::IntoRawDescriptor;
    use serde::Deserializer;

    pub use super::serialize_descriptor as serialize;

    pub fn deserialize<'de, D>(de: D) -> std::result::Result<RawDescriptor, D::Error>
    where
        D: Deserializer<'de>,
    {
        super::deserialize_descriptor(de).map(IntoRawDescriptor::into_raw_descriptor)
    }
}

/// Module that exports `serialize`/`deserialize` functions for use with `#[serde(with = "...")]`
/// attribute.
///
/// # Examples
///
/// ```
/// use std::fs::File;
/// use serde::{Deserialize, Serialize};
/// use base::platform::RawDescriptor;
///
/// #[derive(Serialize, Deserialize)]
/// struct FileContainer {
///     #[serde(with = "base::platform::with_as_descriptor")]
///     file: File,
/// }
/// ```
pub mod with_as_descriptor {
    use crate::descriptor::{AsRawDescriptor, FromRawDescriptor, IntoRawDescriptor};
    use serde::{Deserializer, Serializer};

    pub fn serialize<S: Serializer>(
        rd: &dyn AsRawDescriptor,
        se: S,
    ) -> std::result::Result<S::Ok, S::Error> {
        super::serialize_descriptor(&rd.as_raw_descriptor(), se)
    }

    pub fn deserialize<'de, D, T>(de: D) -> std::result::Result<T, D::Error>
    where
        D: Deserializer<'de>,
        T: FromRawDescriptor,
    {
        super::deserialize_descriptor(de)
            .map(IntoRawDescriptor::into_raw_descriptor)
            .map(|rd| unsafe { T::from_raw_descriptor(rd) })
    }
}

/// A simple wrapper around `File` that implements `Serialize`/`Deserialize`, which is useful when
/// the `#[serde(with = "with_as_descriptor")]` trait is infeasible, such as for a field with type
/// `Option<File>`.
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
pub struct FileSerdeWrapper(#[serde(with = "with_as_descriptor")] pub File);

impl fmt::Debug for FileSerdeWrapper {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl From<File> for FileSerdeWrapper {
    fn from(file: File) -> Self {
        FileSerdeWrapper(file)
    }
}

impl From<FileSerdeWrapper> for File {
    fn from(f: FileSerdeWrapper) -> File {
        f.0
    }
}

impl Deref for FileSerdeWrapper {
    type Target = File;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for FileSerdeWrapper {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

#[cfg(test)]
mod tests {
    use super::super::{
        deserialize_with_descriptors, with_as_descriptor, with_raw_descriptor, AsRawDescriptor,
        FileSerdeWrapper, FromRawDescriptor, RawDescriptor, SafeDescriptor, SerializeDescriptors,
    };

    use std::{collections::HashMap, fs::File, mem::ManuallyDrop};

    use serde::{de::DeserializeOwned, Deserialize, Serialize};
    use tempfile::tempfile;

    fn deserialize<T: DeserializeOwned>(json: &str, descriptors: &[RawDescriptor]) -> T {
        let mut safe_descriptors = descriptors
            .iter()
            .map(|&v| Some(unsafe { SafeDescriptor::from_raw_descriptor(v) }))
            .collect();

        let res =
            deserialize_with_descriptors(|| serde_json::from_str(json), &mut safe_descriptors)
                .unwrap();

        assert!(safe_descriptors.iter().all(|v| v.is_none()));

        res
    }

    #[test]
    fn raw() {
        #[derive(Serialize, Deserialize, PartialEq, Debug)]
        struct RawContainer {
            #[serde(with = "with_raw_descriptor")]
            rd: RawDescriptor,
        }
        // Specifically chosen to not overlap a real descriptor to avoid having to allocate any
        // descriptors for this test.
        let fake_rd = 5_123_457_i32;
        let v = RawContainer {
            rd: fake_rd as RawDescriptor,
        };
        let v_serialize = SerializeDescriptors::new(&v);
        let json = serde_json::to_string(&v_serialize).unwrap();
        let descriptors = v_serialize.into_descriptors();
        let res = deserialize(&json, &descriptors);
        assert_eq!(v, res);
    }

    #[test]
    fn file() {
        #[derive(Serialize, Deserialize)]
        struct FileContainer {
            #[serde(with = "with_as_descriptor")]
            file: File,
        }

        let v = FileContainer {
            file: tempfile().unwrap(),
        };
        let v_serialize = SerializeDescriptors::new(&v);
        let json = serde_json::to_string(&v_serialize).unwrap();
        let descriptors = v_serialize.into_descriptors();
        let v = ManuallyDrop::new(v);
        let res: FileContainer = deserialize(&json, &descriptors);
        assert_eq!(v.file.as_raw_descriptor(), res.file.as_raw_descriptor());
    }

    #[test]
    fn option() {
        #[derive(Serialize, Deserialize)]
        struct TestOption {
            a: Option<FileSerdeWrapper>,
            b: Option<FileSerdeWrapper>,
        }

        let v = TestOption {
            a: None,
            b: Some(tempfile().unwrap().into()),
        };
        let v_serialize = SerializeDescriptors::new(&v);
        let json = serde_json::to_string(&v_serialize).unwrap();
        let descriptors = v_serialize.into_descriptors();
        let v = ManuallyDrop::new(v);
        let res: TestOption = deserialize(&json, &descriptors);
        assert!(res.a.is_none());
        assert!(res.b.is_some());
        assert_eq!(
            v.b.as_ref().unwrap().as_raw_descriptor(),
            res.b.unwrap().as_raw_descriptor()
        );
    }

    #[test]
    fn map() {
        let mut v: HashMap<String, FileSerdeWrapper> = HashMap::new();
        v.insert("a".into(), tempfile().unwrap().into());
        v.insert("b".into(), tempfile().unwrap().into());
        v.insert("c".into(), tempfile().unwrap().into());
        let v_serialize = SerializeDescriptors::new(&v);
        let json = serde_json::to_string(&v_serialize).unwrap();
        let descriptors = v_serialize.into_descriptors();
        // Prevent the files in `v` from dropping while allowing the HashMap itself to drop. It is
        // done this way to prevent a double close of the files (which should reside in `res`)
        // without triggering the leak sanitizer on `v`'s HashMap heap memory.
        let v: HashMap<_, _> = v
            .into_iter()
            .map(|(k, v)| (k, ManuallyDrop::new(v)))
            .collect();
        let res: HashMap<String, FileSerdeWrapper> = deserialize(&json, &descriptors);

        assert_eq!(v.len(), res.len());
        for (k, v) in v.iter() {
            assert_eq!(
                res.get(k).unwrap().as_raw_descriptor(),
                v.as_raw_descriptor()
            );
        }
    }
}
