use chrono::offset::Utc;
use chrono::prelude::*;
use data_encoding::BASE64URL;
use std::collections::{HashMap, HashSet};
use std::iter::FromIterator;

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

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,
    version: u32,
    consistent_snapshot: bool,
    expires: String,
    keys: Vec<crypto::PublicKey>,
    root: metadata::RoleDefinition,
    snapshot: metadata::RoleDefinition,
    targets: metadata::RoleDefinition,
    timestamp: metadata::RoleDefinition,
}

impl RootMetadata {
    pub fn from(meta: &metadata::RootMetadata) -> Result<Self> {
        let mut keys = meta
            .keys()
            .iter()
            .map(|(_, v)| v.clone())
            .collect::<Vec<crypto::PublicKey>>();
        keys.sort_by_key(|k| k.key_id().clone());

        Ok(RootMetadata {
            typ: metadata::Role::Root,
            version: meta.version(),
            expires: format_datetime(&meta.expires()),
            consistent_snapshot: meta.consistent_snapshot(),
            keys,
            root: meta.root().clone(),
            snapshot: meta.snapshot().clone(),
            targets: meta.targets().clone(),
            timestamp: meta.timestamp().clone(),
        })
    }

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

        let keys_len = self.keys.len();
        let keys = HashMap::from_iter(self.keys.drain(..).map(|k| (k.key_id().clone(), k)));

        if keys.len() != keys_len {
            return Err(Error::IllegalArgument("Cannot have duplicate keys".into()));
        }

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

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

impl RoleDefinition {
    pub fn from(role: &metadata::RoleDefinition) -> Result<Self> {
        let mut key_ids = role
            .key_ids()
            .iter()
            .cloned()
            .collect::<Vec<crypto::KeyId>>();
        key_ids.sort();

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

    pub fn try_into(mut 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 key_ids = self.key_ids.drain(0..).collect::<HashSet<crypto::KeyId>>();
        let dupes = vec_len - key_ids.len();

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

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

#[derive(Serialize, Deserialize)]
pub struct TimestampMetadata {
    #[serde(rename = "type")]
    typ: metadata::Role,
    version: u32,
    expires: String,
    snapshot: metadata::MetadataDescription,
}

impl TimestampMetadata {
    pub fn from(metadata: &metadata::TimestampMetadata) -> Result<Self> {
        Ok(TimestampMetadata {
            typ: metadata::Role::Timestamp,
            version: metadata.version(),
            expires: format_datetime(metadata.expires()),
            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 datetime metdata labeled as {:?}",
                self.typ
            )));
        }

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

#[derive(Serialize, Deserialize)]
pub struct SnapshotMetadata {
    #[serde(rename = "type")]
    typ: metadata::Role,
    version: u32,
    expires: String,
    meta: HashMap<metadata::MetadataPath, metadata::MetadataDescription>,
}

impl SnapshotMetadata {
    pub fn from(metadata: &metadata::SnapshotMetadata) -> Result<Self> {
        Ok(SnapshotMetadata {
            typ: metadata::Role::Snapshot,
            version: metadata.version(),
            expires: format_datetime(&metadata.expires()),
            meta: metadata.meta().clone(),
        })
    }

    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
            )));
        }

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

#[derive(Serialize, Deserialize)]
pub struct TargetsMetadata {
    #[serde(rename = "type")]
    typ: metadata::Role,
    version: u32,
    expires: String,
    targets: HashMap<metadata::VirtualTargetPath, 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,
            version: metadata.version(),
            expires: format_datetime(&metadata.expires()),
            targets: metadata.targets().clone(),
            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
            )));
        }

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

#[derive(Serialize, Deserialize)]
pub struct PublicKey {
    #[serde(rename = "type")]
    typ: crypto::KeyType,
    scheme: crypto::SignatureScheme,
    public_key: String,
}

impl PublicKey {
    pub fn new(
        typ: crypto::KeyType,
        scheme: crypto::SignatureScheme,
        public_key_bytes: &[u8],
    ) -> Self {
        PublicKey {
            typ,
            scheme,
            public_key: BASE64URL.encode(public_key_bytes),
        }
    }

    pub fn public_key(&self) -> &String {
        &self.public_key
    }

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

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

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

impl Delegation {
    pub fn from(meta: &metadata::Delegation) -> Self {
        let mut paths = meta
            .paths()
            .iter()
            .cloned()
            .collect::<Vec<metadata::VirtualTargetPath>>();
        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::VirtualTargetPath>>();
        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 {
    keys: Vec<crypto::PublicKey>,
    roles: Vec<metadata::Delegation>,
}

impl Delegations {
    pub fn from(delegations: &metadata::Delegations) -> Delegations {
        let mut keys = delegations
            .keys()
            .iter()
            .map(|(_, k)| k.clone())
            .collect::<Vec<crypto::PublicKey>>();
        keys.sort();

        Delegations {
            keys,
            roles: delegations.roles().clone(),
        }
    }

    pub fn try_into(mut self) -> Result<metadata::Delegations> {
        let keys_len = self.keys.len();
        let keys = self.keys.drain(..).collect::<HashSet<crypto::PublicKey>>();
        if keys.len() != keys_len {
            return Err(Error::Encoding("Cannot have duplicate keys".into()));
        }
        metadata::Delegations::new(&keys, self.roles)
    }
}

#[derive(Deserialize)]
pub struct TargetDescription {
    size: u64,
    hashes: HashMap<crypto::HashAlgorithm, crypto::HashValue>,
}

impl TargetDescription {
    pub fn try_into(self) -> Result<metadata::TargetDescription> {
        metadata::TargetDescription::new(self.size, self.hashes)
    }
}

#[derive(Deserialize)]
pub struct MetadataDescription {
    version: u32,
    size: usize,
    hashes: HashMap<crypto::HashAlgorithm, crypto::HashValue>,
}

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