// Copyright 2018 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.

use {
    crate::errors::{
        BlobIdFromSliceError, BlobIdParseError, CupMissingField, ResolutionContextError,
    },
    fidl_fuchsia_pkg as fidl,
    proptest_derive::Arbitrary,
    serde::{Deserialize, Serialize},
    std::{fmt, str},
    typed_builder::TypedBuilder,
};

pub(crate) const BLOB_ID_SIZE: usize = 32;

/// Convenience wrapper type for the autogenerated FIDL `BlobId`.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize, Arbitrary)]
pub struct BlobId(#[serde(with = "hex_serde")] [u8; BLOB_ID_SIZE]);

impl BlobId {
    /// Parse a `BlobId` from a string containing 32 lower-case hex encoded bytes.
    ///
    /// # Examples
    /// ```
    /// let s = "00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100";
    /// assert_eq!(
    ///     BlobId::parse(s),
    ///     s.parse()
    /// );
    /// ```
    pub fn parse(s: &str) -> Result<Self, BlobIdParseError> {
        s.parse()
    }
    /// Obtain a slice of bytes representing the `BlobId`.
    pub fn as_bytes(&self) -> &[u8] {
        &self.0[..]
    }
}

impl str::FromStr for BlobId {
    type Err = BlobIdParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let bytes = hex::decode(s)?;
        if bytes.len() != BLOB_ID_SIZE {
            return Err(BlobIdParseError::InvalidLength(bytes.len()));
        }
        if s.chars().any(|c| c.is_uppercase()) {
            return Err(BlobIdParseError::CannotContainUppercase);
        }
        let mut res: [u8; BLOB_ID_SIZE] = [0; BLOB_ID_SIZE];
        res.copy_from_slice(&bytes[..]);
        Ok(Self(res))
    }
}

impl From<[u8; BLOB_ID_SIZE]> for BlobId {
    fn from(bytes: [u8; BLOB_ID_SIZE]) -> Self {
        Self(bytes)
    }
}

impl From<fidl::BlobId> for BlobId {
    fn from(id: fidl::BlobId) -> Self {
        Self(id.merkle_root)
    }
}

impl From<BlobId> for fidl::BlobId {
    fn from(id: BlobId) -> Self {
        Self { merkle_root: id.0 }
    }
}

impl From<fuchsia_hash::Hash> for BlobId {
    fn from(hash: fuchsia_hash::Hash) -> Self {
        Self(hash.into())
    }
}

impl TryFrom<&[u8]> for BlobId {
    type Error = BlobIdFromSliceError;

    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
        Ok(Self(bytes.try_into().map_err(|_| Self::Error::InvalidLength(bytes.len()))?))
    }
}

impl From<BlobId> for fuchsia_hash::Hash {
    fn from(id: BlobId) -> Self {
        id.0.into()
    }
}

impl fmt::Display for BlobId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(&hex::encode(self.0))
    }
}

impl fmt::Debug for BlobId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(&self.to_string())
    }
}

/// Convenience wrapper type for the autogenerated FIDL `BlobInfo`.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Arbitrary)]
pub struct BlobInfo {
    pub blob_id: BlobId,
    pub length: u64,
}

impl BlobInfo {
    pub fn new(blob_id: BlobId, length: u64) -> Self {
        BlobInfo { blob_id: blob_id, length: length }
    }
}

impl From<fidl::BlobInfo> for BlobInfo {
    fn from(info: fidl::BlobInfo) -> Self {
        BlobInfo { blob_id: info.blob_id.into(), length: info.length }
    }
}

impl From<BlobInfo> for fidl::BlobInfo {
    fn from(info: BlobInfo) -> Self {
        Self { blob_id: info.blob_id.into(), length: info.length }
    }
}

/// Convenience wrapper type for the autogenerated FIDL `ResolutionContext`.
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ResolutionContext {
    blob_id: Option<BlobId>,
}

impl ResolutionContext {
    /// Creates an empty resolution context.
    pub fn new() -> Self {
        Self { blob_id: None }
    }

    /// The ResolutionContext's optional blob id.
    pub fn blob_id(&self) -> Option<&BlobId> {
        self.blob_id.as_ref()
    }
}

impl From<BlobId> for ResolutionContext {
    fn from(blob_id: BlobId) -> Self {
        Self { blob_id: Some(blob_id) }
    }
}

impl From<fuchsia_hash::Hash> for ResolutionContext {
    fn from(hash: fuchsia_hash::Hash) -> Self {
        Self { blob_id: Some(hash.into()) }
    }
}

impl TryFrom<&[u8]> for ResolutionContext {
    type Error = ResolutionContextError;

    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
        if bytes.is_empty() {
            Ok(Self { blob_id: None })
        } else {
            Ok(Self { blob_id: Some(bytes.try_into().map_err(Self::Error::InvalidBlobId)?) })
        }
    }
}

impl TryFrom<&fidl::ResolutionContext> for ResolutionContext {
    type Error = ResolutionContextError;

    fn try_from(context: &fidl::ResolutionContext) -> Result<Self, Self::Error> {
        Self::try_from(context.bytes.as_slice())
    }
}

impl From<ResolutionContext> for Vec<u8> {
    fn from(context: ResolutionContext) -> Self {
        match context.blob_id {
            Some(blob_id) => blob_id.as_bytes().to_vec(),
            None => vec![],
        }
    }
}

impl From<ResolutionContext> for fidl::ResolutionContext {
    fn from(context: ResolutionContext) -> Self {
        Self { bytes: context.into() }
    }
}

mod hex_serde {
    use {super::BLOB_ID_SIZE, hex::FromHex, serde::Deserialize};

    pub fn serialize<S>(bytes: &[u8; BLOB_ID_SIZE], serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let s = hex::encode(bytes);
        serializer.serialize_str(&s)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<[u8; BLOB_ID_SIZE], D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let value = String::deserialize(deserializer)?;
        <[u8; BLOB_ID_SIZE]>::from_hex(value.as_bytes())
            .map_err(|e| serde::de::Error::custom(format!("bad hex value: {:?}: {}", value, e)))
    }
}

#[derive(Clone, Debug, Eq, PartialEq, TypedBuilder)]
pub struct CupData {
    #[builder(default, setter(into))]
    pub request: Vec<u8>,
    #[builder(default, setter(into))]
    pub key_id: u64,
    #[builder(default, setter(into))]
    pub nonce: [u8; 32],
    #[builder(default, setter(into))]
    pub response: Vec<u8>,
    #[builder(default, setter(into))]
    pub signature: Vec<u8>,
}

impl From<CupData> for fidl::CupData {
    fn from(c: CupData) -> Self {
        fidl::CupData {
            request: Some(c.request),
            key_id: Some(c.key_id),
            nonce: Some(c.nonce),
            response: Some(c.response),
            signature: Some(c.signature),
            ..Default::default()
        }
    }
}

impl TryFrom<fidl::CupData> for CupData {
    type Error = CupMissingField;
    fn try_from(c: fidl::CupData) -> Result<Self, Self::Error> {
        Ok(CupData::builder()
            .request(c.request.ok_or(CupMissingField::Request)?)
            .response(c.response.ok_or(CupMissingField::Response)?)
            .key_id(c.key_id.ok_or(CupMissingField::KeyId)?)
            .nonce(c.nonce.ok_or(CupMissingField::Nonce)?)
            .signature(c.signature.ok_or(CupMissingField::Signature)?)
            .build())
    }
}

#[cfg(test)]
mod test_blob_id {
    use {super::*, assert_matches::assert_matches, proptest::prelude::*};

    prop_compose! {
        fn invalid_hex_char()(c in "[[:ascii:]&&[^0-9a-fA-F]]") -> char {
            assert_eq!(c.len(), 1);
            c.chars().next().unwrap()
        }
    }

    proptest! {
        #![proptest_config(ProptestConfig{
            // Disable persistence to avoid the warning for not running in the
            // source code directory (since we're running on a Fuchsia target)
            failure_persistence: None,
            .. ProptestConfig::default()
        })]

        #[test]
        fn parse_is_inverse_of_display(ref id in "[0-9a-f]{64}") {
            prop_assert_eq!(
                id,
                &format!("{}", id.parse::<BlobId>().unwrap())
            );
        }

        #[test]
        fn parse_is_inverse_of_debug(ref id in "[0-9a-f]{64}") {
            prop_assert_eq!(
                id,
                &format!("{:?}", id.parse::<BlobId>().unwrap())
            );
        }

        #[test]
        fn parse_rejects_uppercase(ref id in "[0-9A-F]{64}") {
            prop_assert_eq!(
                id.parse::<BlobId>(),
                Err(BlobIdParseError::CannotContainUppercase)
            );
        }

        #[test]
        fn parse_rejects_unexpected_characters(mut id in "[0-9a-f]{64}", c in invalid_hex_char(), index in 0usize..63) {
            id.remove(index);
            id.insert(index, c);
            prop_assert_eq!(
                id.parse::<BlobId>(),
                Err(BlobIdParseError::FromHexError(
                    hex::FromHexError::InvalidHexCharacter { c: c, index: index }
                ))
            );
        }

        #[test]
        fn parse_expects_even_sized_strings(ref id in "[0-9a-f]([0-9a-f]{2})*") {
            prop_assert_eq!(
                id.parse::<BlobId>(),
                Err(BlobIdParseError::FromHexError(hex::FromHexError::OddLength))
            );
        }

        #[test]
        fn parse_expects_precise_count_of_bytes(ref id in "([0-9a-f]{2})*") {
            prop_assume!(id.len() != BLOB_ID_SIZE * 2);
            prop_assert_eq!(
                id.parse::<BlobId>(),
                Err(BlobIdParseError::InvalidLength(id.len() / 2))
            );
        }

        #[test]
        fn fidl_conversions_are_inverses(id: BlobId) {
            let temp : fidl::BlobId = id.into();
            prop_assert_eq!(
                id,
                BlobId::from(temp)
            );
        }
    }

    #[test]
    fn try_from_slice_rejects_invalid_length() {
        assert_matches!(
            BlobId::try_from([0u8; BLOB_ID_SIZE - 1].as_slice()),
            Err(BlobIdFromSliceError::InvalidLength(31))
        );
        assert_matches!(
            BlobId::try_from([0u8; BLOB_ID_SIZE + 1].as_slice()),
            Err(BlobIdFromSliceError::InvalidLength(33))
        );
    }

    #[test]
    fn try_from_slice_succeeds() {
        let bytes = [1u8; 32];
        assert_eq!(BlobId::try_from(bytes.as_slice()).unwrap().as_bytes(), bytes.as_slice());
    }
}

#[cfg(test)]
mod test_resolution_context {
    use {super::*, assert_matches::assert_matches};

    #[test]
    fn try_from_slice_succeeds() {
        assert_eq!(
            ResolutionContext::try_from([].as_slice()).unwrap(),
            ResolutionContext { blob_id: None }
        );

        assert_eq!(
            ResolutionContext::try_from([1u8; 32].as_slice()).unwrap(),
            ResolutionContext { blob_id: Some([1u8; 32].into()) }
        );
    }

    #[test]
    fn try_from_slice_fails() {
        assert_matches!(
            ResolutionContext::try_from([1u8].as_slice()),
            Err(ResolutionContextError::InvalidBlobId(_))
        );
    }

    #[test]
    fn into_vec() {
        assert_eq!(Vec::from(ResolutionContext::new()), Vec::<u8>::new());

        assert_eq!(Vec::from(ResolutionContext::from(BlobId::from([1u8; 32]))), vec![1u8; 32]);
    }

    #[test]
    fn try_from_fidl_succeeds() {
        assert_eq!(
            ResolutionContext::try_from(&fidl::ResolutionContext { bytes: vec![] }).unwrap(),
            ResolutionContext { blob_id: None }
        );

        assert_eq!(
            ResolutionContext::try_from(&fidl::ResolutionContext { bytes: vec![1u8; 32] }).unwrap(),
            ResolutionContext { blob_id: Some([1u8; 32].into()) }
        );
    }

    #[test]
    fn try_from_fidl_fails() {
        assert_matches!(
            ResolutionContext::try_from(&fidl::ResolutionContext { bytes: vec![1u8; 1] }),
            Err(ResolutionContextError::InvalidBlobId(_))
        );
    }

    #[test]
    fn into_fidl() {
        assert_eq!(
            fidl::ResolutionContext::from(ResolutionContext::new()),
            fidl::ResolutionContext { bytes: vec![] }
        );

        assert_eq!(
            fidl::ResolutionContext::from(ResolutionContext::from(BlobId::from([1u8; 32]))),
            fidl::ResolutionContext { bytes: vec![1u8; 32] }
        );
    }
}
