use chrono::offset::Utc;
use chrono::prelude::*;
use serde_derive::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashSet};

use crate::crypto;
use crate::error::Error;
use crate::metadata::{self, Metadata};
use crate::Result;

const SPEC_VERSION: &str = "1.0";

fn parse_datetime(ts: &str) -> Result<DateTime<Utc>> {
    Utc.datetime_from_str(ts, "%FT%TZ")
        .map_err(|e| Error::Encoding(format!("Can't parse DateTime: {:?}", e)))
}

fn format_datetime(ts: &DateTime<Utc>) -> String {
    format!(
        "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z",
        ts.year(),
        ts.month(),
        ts.day(),
        ts.hour(),
        ts.minute(),
        ts.second()
    )
}

#[derive(Debug, Serialize, Deserialize)]
pub struct RootMetadata {
    #[serde(rename = "_type")]
    typ: metadata::Role,
    spec_version: String,
    version: u32,
    consistent_snapshot: bool,
    expires: String,
    #[serde(deserialize_with = "deserialize_reject_duplicates::deserialize")]
    keys: BTreeMap<crypto::KeyId, crypto::PublicKey>,
    roles: RoleDefinitions,
}

impl RootMetadata {
    pub fn from(meta: &metadata::RootMetadata) -> Result<Self> {
        Ok(RootMetadata {
            typ: metadata::Role::Root,
            spec_version: SPEC_VERSION.to_string(),
            version: meta.version(),
            expires: format_datetime(meta.expires()),
            consistent_snapshot: meta.consistent_snapshot(),
            keys: meta
                .keys()
                .iter()
                .map(|(id, key)| (id.clone(), key.clone()))
                .collect(),
            roles: RoleDefinitions {
                root: meta.root().clone(),
                snapshot: meta.snapshot().clone(),
                targets: meta.targets().clone(),
                timestamp: meta.timestamp().clone(),
            },
        })
    }

    pub fn try_into(self) -> Result<metadata::RootMetadata> {
        if self.typ != metadata::Role::Root {
            return Err(Error::Encoding(format!(
                "Attempted to decode root metdata labeled as {:?}",
                self.typ
            )));
        }

        if self.spec_version != SPEC_VERSION {
            return Err(Error::Encoding(format!(
                "Unknown spec version {}",
                self.spec_version
            )));
        }

        // Ignore all keys with incorrect key IDs. We should give an error if the key ID is not
        // correct according to TUF spec. However, due to backward compatibility, we may receive
        // metadata with key IDs generated by TUF 0.9. We simply ignore those old keys.
        let keys_with_correct_key_id = self
            .keys
            .into_iter()
            .filter(|(key_id, pkey)| key_id == pkey.key_id())
            .collect();

        metadata::RootMetadata::new(
            self.version,
            parse_datetime(&self.expires)?,
            self.consistent_snapshot,
            keys_with_correct_key_id,
            self.roles.root,
            self.roles.snapshot,
            self.roles.targets,
            self.roles.timestamp,
        )
    }
}

#[derive(Debug, Serialize, Deserialize)]
struct RoleDefinitions {
    root: metadata::RoleDefinition,
    snapshot: metadata::RoleDefinition,
    targets: metadata::RoleDefinition,
    timestamp: metadata::RoleDefinition,
}

#[derive(Serialize, Deserialize)]
pub struct RoleDefinition {
    threshold: u32,
    #[serde(rename = "keyids")]
    key_ids: Vec<crypto::KeyId>,
}

impl RoleDefinition {
    pub fn from(role: &metadata::RoleDefinition) -> Result<Self> {
        let key_ids = role.key_ids().to_vec();

        Ok(RoleDefinition {
            threshold: role.threshold(),
            key_ids,
        })
    }

    pub fn try_into(self) -> Result<metadata::RoleDefinition> {
        let vec_len = self.key_ids.len();
        if vec_len < 1 {
            return Err(Error::Encoding(
                "Role defined with no assoiciated key IDs.".into(),
            ));
        }

        let mut seen = HashSet::new();
        let mut dupes = 0;
        for key_id in self.key_ids.iter() {
            if !seen.insert(key_id) {
                dupes += 1;
            }
        }

        if dupes != 0 {
            return Err(Error::Encoding(format!(
                "Found {} duplicate key IDs.",
                dupes
            )));
        }

        metadata::RoleDefinition::new(self.threshold, self.key_ids)
    }
}

#[derive(Serialize, Deserialize)]
pub struct TimestampMetadata {
    #[serde(rename = "_type")]
    typ: metadata::Role,
    spec_version: String,
    version: u32,
    expires: String,
    meta: TimestampMeta,
}

#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct TimestampMeta {
    #[serde(rename = "snapshot.json")]
    snapshot: metadata::MetadataDescription,
}

impl TimestampMetadata {
    pub fn from(metadata: &metadata::TimestampMetadata) -> Result<Self> {
        Ok(TimestampMetadata {
            typ: metadata::Role::Timestamp,
            spec_version: SPEC_VERSION.to_string(),
            version: metadata.version(),
            expires: format_datetime(metadata.expires()),
            meta: TimestampMeta {
                snapshot: metadata.snapshot().clone(),
            },
        })
    }

    pub fn try_into(self) -> Result<metadata::TimestampMetadata> {
        if self.typ != metadata::Role::Timestamp {
            return Err(Error::Encoding(format!(
                "Attempted to decode timestamp metdata labeled as {:?}",
                self.typ
            )));
        }

        if self.spec_version != SPEC_VERSION {
            return Err(Error::Encoding(format!(
                "Unknown spec version {}",
                self.spec_version
            )));
        }

        metadata::TimestampMetadata::new(
            self.version,
            parse_datetime(&self.expires)?,
            self.meta.snapshot,
        )
    }
}

#[derive(Serialize, Deserialize)]
pub struct SnapshotMetadata {
    #[serde(rename = "_type")]
    typ: metadata::Role,
    spec_version: String,
    version: u32,
    expires: String,
    #[serde(deserialize_with = "deserialize_reject_duplicates::deserialize")]
    meta: BTreeMap<String, metadata::MetadataDescription>,
}

impl SnapshotMetadata {
    pub fn from(metadata: &metadata::SnapshotMetadata) -> Result<Self> {
        Ok(SnapshotMetadata {
            typ: metadata::Role::Snapshot,
            spec_version: SPEC_VERSION.to_string(),
            version: metadata.version(),
            expires: format_datetime(metadata.expires()),
            meta: metadata
                .meta()
                .iter()
                .map(|(p, d)| (format!("{}.json", p), d.clone()))
                .collect(),
        })
    }

    pub fn try_into(self) -> Result<metadata::SnapshotMetadata> {
        if self.typ != metadata::Role::Snapshot {
            return Err(Error::Encoding(format!(
                "Attempted to decode snapshot metdata labeled as {:?}",
                self.typ
            )));
        }

        if self.spec_version != SPEC_VERSION {
            return Err(Error::Encoding(format!(
                "Unknown spec version {}",
                self.spec_version
            )));
        }

        metadata::SnapshotMetadata::new(
            self.version,
            parse_datetime(&self.expires)?,
            self.meta
                .into_iter()
                .map(|(p, d)| {
                    if !p.ends_with(".json") {
                        return Err(Error::Encoding(format!(
                            "Metadata does not end with .json: {}",
                            p
                        )));
                    }

                    let s = p.split_at(p.len() - ".json".len()).0.to_owned();
                    let p = metadata::MetadataPath::new(s)?;

                    Ok((p, d))
                })
                .collect::<Result<_>>()?,
        )
    }
}

#[derive(Serialize, Deserialize)]
pub struct TargetsMetadata {
    #[serde(rename = "_type")]
    typ: metadata::Role,
    spec_version: String,
    version: u32,
    expires: String,
    targets: BTreeMap<metadata::TargetPath, metadata::TargetDescription>,
    #[serde(skip_serializing_if = "Option::is_none")]
    delegations: Option<metadata::Delegations>,
}

impl TargetsMetadata {
    pub fn from(metadata: &metadata::TargetsMetadata) -> Result<Self> {
        Ok(TargetsMetadata {
            typ: metadata::Role::Targets,
            spec_version: SPEC_VERSION.to_string(),
            version: metadata.version(),
            expires: format_datetime(metadata.expires()),
            targets: metadata
                .targets()
                .iter()
                .map(|(p, d)| (p.clone(), d.clone()))
                .collect(),
            delegations: metadata.delegations().cloned(),
        })
    }

    pub fn try_into(self) -> Result<metadata::TargetsMetadata> {
        if self.typ != metadata::Role::Targets {
            return Err(Error::Encoding(format!(
                "Attempted to decode targets metdata labeled as {:?}",
                self.typ
            )));
        }

        if self.spec_version != SPEC_VERSION {
            return Err(Error::Encoding(format!(
                "Unknown spec version {}",
                self.spec_version
            )));
        }

        metadata::TargetsMetadata::new(
            self.version,
            parse_datetime(&self.expires)?,
            self.targets.into_iter().collect(),
            self.delegations,
        )
    }
}

#[derive(Serialize, Deserialize)]
pub struct PublicKey {
    keytype: crypto::KeyType,
    scheme: crypto::SignatureScheme,
    #[serde(skip_serializing_if = "Option::is_none")]
    keyid_hash_algorithms: Option<Vec<String>>,
    keyval: PublicKeyValue,
}

impl PublicKey {
    pub fn new(
        keytype: crypto::KeyType,
        scheme: crypto::SignatureScheme,
        keyid_hash_algorithms: Option<Vec<String>>,
        public_key: String,
    ) -> Self {
        PublicKey {
            keytype,
            scheme,
            keyid_hash_algorithms,
            keyval: PublicKeyValue { public: public_key },
        }
    }

    pub fn public_key(&self) -> &str {
        &self.keyval.public
    }

    pub fn scheme(&self) -> &crypto::SignatureScheme {
        &self.scheme
    }

    pub fn keytype(&self) -> &crypto::KeyType {
        &self.keytype
    }

    pub fn keyid_hash_algorithms(&self) -> &Option<Vec<String>> {
        &self.keyid_hash_algorithms
    }
}

#[derive(Serialize, Deserialize)]
pub struct PublicKeyValue {
    public: String,
}

#[derive(Serialize, Deserialize)]
pub struct Delegation {
    role: metadata::MetadataPath,
    terminating: bool,
    threshold: u32,
    #[serde(rename = "keyids")]
    key_ids: Vec<crypto::KeyId>,
    paths: Vec<metadata::TargetPath>,
}

impl Delegation {
    pub fn from(meta: &metadata::Delegation) -> Self {
        let mut paths = meta
            .paths()
            .iter()
            .cloned()
            .collect::<Vec<metadata::TargetPath>>();
        paths.sort();
        let mut key_ids = meta
            .key_ids()
            .iter()
            .cloned()
            .collect::<Vec<crypto::KeyId>>();
        key_ids.sort();

        Delegation {
            role: meta.role().clone(),
            terminating: meta.terminating(),
            threshold: meta.threshold(),
            key_ids,
            paths,
        }
    }

    pub fn try_into(self) -> Result<metadata::Delegation> {
        let paths = self
            .paths
            .iter()
            .cloned()
            .collect::<HashSet<metadata::TargetPath>>();
        if paths.len() != self.paths.len() {
            return Err(Error::Encoding("Non-unique delegation paths.".into()));
        }

        let key_ids = self
            .key_ids
            .iter()
            .cloned()
            .collect::<HashSet<crypto::KeyId>>();
        if key_ids.len() != self.key_ids.len() {
            return Err(Error::Encoding("Non-unique delegation key IDs.".into()));
        }

        metadata::Delegation::new(self.role, self.terminating, self.threshold, key_ids, paths)
    }
}

#[derive(Serialize, Deserialize)]
pub struct Delegations {
    #[serde(deserialize_with = "deserialize_reject_duplicates::deserialize")]
    keys: BTreeMap<crypto::KeyId, crypto::PublicKey>,
    roles: Vec<metadata::Delegation>,
}

impl Delegations {
    pub fn from(delegations: &metadata::Delegations) -> Delegations {
        Delegations {
            keys: delegations
                .keys()
                .iter()
                .map(|(id, key)| (id.clone(), key.clone()))
                .collect(),
            roles: delegations.roles().clone(),
        }
    }

    pub fn try_into(self) -> Result<metadata::Delegations> {
        metadata::Delegations::new(self.keys.into_iter().collect(), self.roles)
    }
}

#[derive(Serialize, Deserialize)]
pub struct TargetDescription {
    length: u64,
    hashes: BTreeMap<crypto::HashAlgorithm, crypto::HashValue>,
    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
    custom: BTreeMap<String, serde_json::Value>,
}

impl TargetDescription {
    pub fn from(description: &metadata::TargetDescription) -> TargetDescription {
        TargetDescription {
            length: description.length(),
            hashes: description
                .hashes()
                .iter()
                .map(|(k, v)| (k.clone(), v.clone()))
                .collect(),
            custom: description
                .custom()
                .iter()
                .map(|(k, v)| (k.clone(), v.clone()))
                .collect(),
        }
    }

    pub fn try_into(self) -> Result<metadata::TargetDescription> {
        metadata::TargetDescription::new(
            self.length,
            self.hashes.into_iter().collect(),
            self.custom.into_iter().collect(),
        )
    }
}

#[derive(Deserialize)]
pub struct MetadataDescription {
    version: u32,
    #[serde(default)]
    length: Option<usize>,
    #[serde(default)]
    hashes: BTreeMap<crypto::HashAlgorithm, crypto::HashValue>,
}

impl MetadataDescription {
    pub fn try_into(self) -> Result<metadata::MetadataDescription> {
        metadata::MetadataDescription::new(
            self.version,
            self.length,
            self.hashes.into_iter().collect(),
        )
    }
}

/// Custom deserialize to reject duplicate keys.
mod deserialize_reject_duplicates {
    use serde::de::{Deserialize, Deserializer, Error, MapAccess, Visitor};
    use std::collections::BTreeMap;
    use std::fmt;
    use std::marker::PhantomData;
    use std::result::Result;

    pub fn deserialize<'de, K, V, D>(deserializer: D) -> Result<BTreeMap<K, V>, D::Error>
    where
        K: Deserialize<'de> + Ord,
        V: Deserialize<'de>,
        D: Deserializer<'de>,
    {
        struct BTreeVisitor<K, V> {
            marker: PhantomData<(K, V)>,
        }

        impl<'de, K, V> Visitor<'de> for BTreeVisitor<K, V>
        where
            K: Deserialize<'de> + Ord,
            V: Deserialize<'de>,
        {
            type Value = BTreeMap<K, V>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("map")
            }

            fn visit_map<M>(self, mut access: M) -> std::result::Result<Self::Value, M::Error>
            where
                M: MapAccess<'de>,
            {
                let mut map = BTreeMap::new();
                while let Some((key, value)) = access.next_entry()? {
                    if map.insert(key, value).is_some() {
                        return Err(M::Error::custom("Cannot have duplicate keys"));
                    }
                }
                Ok(map)
            }
        }

        deserializer.deserialize_map(BTreeVisitor {
            marker: PhantomData,
        })
    }
}
