use chrono::{DateTime, UTC};
use data_encoding::HEXLOWER;
use json;
use ring;
use ring::digest::{digest, SHA256};
use ring::signature::ED25519;
use serde::de::{Deserialize, DeserializeOwned, Deserializer, Error as DeserializeError};
use std::collections::HashMap;
use std::fmt::{self, Display, Formatter, Debug};
use std::marker::PhantomData;
use std::str::FromStr;
use untrusted::Input;

use cjson::canonicalize;
use error::Error;

static HASH_PREFERENCES: &'static [HashType] = &[HashType::Sha512, HashType::Sha256];

#[derive(Eq, PartialEq, Deserialize, Debug)]
pub enum Role {
    Root,
    Targets,
    Timestamp,
    Snapshot,
}

impl FromStr for Role {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "Root" => Ok(Role::Root),
            "Snapshot" => Ok(Role::Snapshot),
            "Targets" => Ok(Role::Targets),
            "Timestamp" => Ok(Role::Timestamp),
            role => Err(Error::UnknownRole(String::from(role))),
        }
    }
}

impl Display for Role {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match *self {
            Role::Root => write!(f, "{}", "root"),
            Role::Targets => write!(f, "{}", "targets"),
            Role::Snapshot => write!(f, "{}", "snapshot"),
            Role::Timestamp => write!(f, "{}", "timestamp"),
        }
    }
}

pub trait RoleType: Debug {
    fn role() -> Role;
}

#[derive(Debug)]
pub struct Root {}
impl RoleType for Root {
    fn role() -> Role {
        Role::Root
    }
}

#[derive(Debug)]
pub struct Targets {}
impl RoleType for Targets {
    fn role() -> Role {
        Role::Targets
    }
}

#[derive(Debug)]
pub struct Timestamp {}
impl RoleType for Timestamp {
    fn role() -> Role {
        Role::Timestamp
    }
}

#[derive(Debug)]
pub struct Snapshot {}
impl RoleType for Snapshot {
    fn role() -> Role {
        Role::Snapshot
    }
}

#[derive(Debug)]
pub struct SignedMetadata<R: RoleType> {
    pub signatures: Vec<Signature>,
    pub signed: json::Value,
    _role: PhantomData<R>,
}

impl<'de, R: RoleType> Deserialize<'de> for SignedMetadata<R> {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::Object(mut object) = Deserialize::deserialize(de)? {
            match (object.remove("signatures"), object.remove("signed")) {
                (Some(a @ json::Value::Array(_)), Some(v @ json::Value::Object(_))) => {
                    Ok(SignedMetadata::<R> {
                        signatures: json::from_value(a).map_err(|e| {
                                DeserializeError::custom(format!("Bad signature data: {}", e))
                            })?,
                        signed: v.clone(),
                        _role: PhantomData,
                    })
                }
                _ => {
                    Err(DeserializeError::custom("Metadata missing 'signed' or 'signatures' \
                                                  section"))
                }
            }
        } else {
            Err(DeserializeError::custom("Metadata was not an object"))
        }
    }
}

pub trait Metadata<R: RoleType>: DeserializeOwned {
    fn expires(&self) -> &DateTime<UTC>;
}


#[derive(Debug, PartialEq)]
pub struct RootMetadata {
    // TODO consistent_snapshot: bool,
    expires: DateTime<UTC>,
    pub version: i32,
    pub keys: HashMap<KeyId, Key>,
    root: RoleDefinition,
    targets: RoleDefinition,
    timestamp: RoleDefinition,
    snapshot: RoleDefinition,
}

impl RootMetadata {
    pub fn role_definition<R: RoleType>(&self) -> &RoleDefinition {
        match R::role() {
            Role::Root => &self.root,
            Role::Targets => &self.targets,
            Role::Timestamp => &self.timestamp,
            Role::Snapshot => &self.snapshot,
        }
    }
}

impl Metadata<Root> for RootMetadata {
    fn expires(&self) -> &DateTime<UTC> {
        &self.expires
    }
}

impl<'de> Deserialize<'de> for RootMetadata {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::Object(mut object) = Deserialize::deserialize(de)? {
            let typ = json::from_value::<Role>(object.remove("_type")
                    .ok_or_else(|| DeserializeError::custom("Field '_type' missing"))?)
                .map_err(|e| {
                    DeserializeError::custom(format!("Field '_type' not a valid role: {}", e))
                })?;

            if typ != Role::Root {
                return Err(DeserializeError::custom("Field '_type' was not 'Root'"));
            }

            let keys = json::from_value(object.remove("keys")
                    .ok_or_else(|| DeserializeError::custom("Field 'keys' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'keys' not a valid key map: {}", e))
                })?;

            let expires = json::from_value(object.remove("expires")
                    .ok_or_else(|| DeserializeError::custom("Field 'expires' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'expires' did not have a valid format: {}", e))
                })?;

            let version = json::from_value(object.remove("version")
                    .ok_or_else(|| DeserializeError::custom("Field 'version' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'version' did not have a valid format: {}", e))
                })?;

            let mut roles = object.remove("roles")
                .and_then(|v| match v {
                    json::Value::Object(o) => Some(o),
                    _ => None,
                })
                .ok_or_else(|| DeserializeError::custom("Field 'roles' missing"))?;

            let root = json::from_value(roles.remove("root")
                    .ok_or_else(|| DeserializeError::custom("Role 'root' missing"))?)
                .map_err(|e| {
                    DeserializeError::custom(format!("Root role definition error: {}", e))
                })?;

            let targets = json::from_value(roles.remove("targets")
                    .ok_or_else(|| DeserializeError::custom("Role 'targets' missing"))?)
                .map_err(|e| {
                    DeserializeError::custom(format!("Targets role definition error: {}", e))
                })?;

            let timestamp = json::from_value(roles.remove("timestamp")
                    .ok_or_else(|| DeserializeError::custom("Role 'timestamp' missing"))?)
                .map_err(|e| {
                    DeserializeError::custom(format!("Timetamp role definition error: {}", e))
                })?;

            let snapshot = json::from_value(roles.remove("snapshot")
                    .ok_or_else(|| DeserializeError::custom("Role 'shapshot' missing"))?)
                .map_err(|e| {
                    DeserializeError::custom(format!("Snapshot role definition error: {}", e))
                })?;

            Ok(RootMetadata {
                expires: expires,
                version: version,
                keys: keys,
                root: root,
                targets: targets,
                timestamp: timestamp,
                snapshot: snapshot,
            })
        } else {
            Err(DeserializeError::custom("Role was not an object"))
        }
    }
}

#[derive(Clone, PartialEq, Debug)]
pub struct RoleDefinition {
    pub key_ids: Vec<KeyId>,
    pub threshold: i32,
}

impl<'de> Deserialize<'de> for RoleDefinition {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::Object(mut object) = Deserialize::deserialize(de)? {
            let key_ids = json::from_value(object.remove("keyids")
                    .ok_or_else(|| DeserializeError::custom("Field 'keyids' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'keyids' not a valid array: {}", e))
                })?;

            let threshold = json::from_value(object.remove("threshold")
                    .ok_or_else(|| DeserializeError::custom("Field 'threshold' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'threshold' not a an int: {}", e))
                })?;

            if threshold <= 0 {
                return Err(DeserializeError::custom("'threshold' must be >= 1"));
            }


            Ok(RoleDefinition {
                key_ids: key_ids,
                threshold: threshold,
            })
        } else {
            Err(DeserializeError::custom("Role definition was not an object"))
        }
    }
}

#[derive(Debug)]
pub struct TargetsMetadata {
    expires: DateTime<UTC>,
    pub version: i32,
    pub delegations: Option<Delegations>,
    pub targets: HashMap<String, TargetInfo>,
}

impl Metadata<Targets> for TargetsMetadata {
    fn expires(&self) -> &DateTime<UTC> {
        &self.expires
    }
}

impl<'de> Deserialize<'de> for TargetsMetadata {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::Object(mut object) = Deserialize::deserialize(de)? {
            let delegations = match object.remove("delegations") {
                // TODO this should accept null / empty object too
                // currently the options are "not present at all" or "completely correct"
                // and everything else errors out
                Some(value) => {
                    Some(json::from_value(value).map_err(|e| {
                            DeserializeError::custom(format!("Bad delegations format: {}", e))
                        })?)
                }
                None => None,
            };

            let expires = json::from_value(object.remove("expires")
                    .ok_or_else(|| DeserializeError::custom("Field 'expires' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'expires did not have a valid format: {}", e))
                })?;

            let version = json::from_value(object.remove("version")
                    .ok_or_else(|| DeserializeError::custom("Field 'version' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'version' did not have a valid format: {}", e))
                })?;

            match object.remove("targets") {
                Some(t) => {
                    let targets =
                        json::from_value(t).map_err(|e| {
                                DeserializeError::custom(format!("Bad targets format: {}", e))
                            })?;

                    Ok(TargetsMetadata {
                        version: version,
                        expires: expires,
                        delegations: delegations,
                        targets: targets,
                    })
                }
                _ => Err(DeserializeError::custom("Signature missing fields".to_string())),
            }
        } else {
            Err(DeserializeError::custom("Role was not an object"))
        }
    }
}


#[derive(Debug)]
pub struct TimestampMetadata {
    expires: DateTime<UTC>,
    pub version: i32,
    pub meta: HashMap<String, MetadataMetadata>,
}

impl Metadata<Timestamp> for TimestampMetadata {
    fn expires(&self) -> &DateTime<UTC> {
        &self.expires
    }
}

impl<'de> Deserialize<'de> for TimestampMetadata {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::Object(mut object) = Deserialize::deserialize(de)? {

            let expires = json::from_value(object.remove("expires")
                    .ok_or_else(|| DeserializeError::custom("Field 'expires' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'expires' did not have a valid format: {}", e))
                })?;

            let version = json::from_value(object.remove("version")
                    .ok_or_else(|| DeserializeError::custom("Field 'version' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'version' did not have a valid format: {}", e))
                })?;

            match object.remove("meta") {
                Some(m) => {
                    let meta = json::from_value(m).map_err(|e| {
                            DeserializeError::custom(format!("Bad meta-meta format: {}", e))
                        })?;

                    Ok(TimestampMetadata {
                        expires: expires,
                        version: version,
                        meta: meta,
                    })
                }
                _ => Err(DeserializeError::custom("Signature missing fields".to_string())),
            }
        } else {
            Err(DeserializeError::custom("Role was not an object"))
        }
    }
}


#[derive(Debug)]
pub struct SnapshotMetadata {
    expires: DateTime<UTC>,
    pub version: i32,
    pub meta: HashMap<String, SnapshotMetadataMetadata>,
}

impl Metadata<Snapshot> for SnapshotMetadata {
    fn expires(&self) -> &DateTime<UTC> {
        &self.expires
    }
}

impl<'de> Deserialize<'de> for SnapshotMetadata {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::Object(mut object) = Deserialize::deserialize(de)? {
            let expires = json::from_value(object.remove("expires")
                    .ok_or_else(|| DeserializeError::custom("Field 'expires' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'expires' did not have a valid format: {}", e))
                })?;

            let version = json::from_value(object.remove("version")
                    .ok_or_else(|| DeserializeError::custom("Field 'version' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'version' did not have a valid format: {}", e))
                })?;

            match object.remove("meta") {
                Some(m) => {
                    let meta = json::from_value(m).map_err(|e| {
                            DeserializeError::custom(format!("Bad meta-meta format: {}", e))
                        })?;

                    Ok(SnapshotMetadata {
                        expires: expires,
                        version: version,
                        meta: meta,
                    })
                }
                _ => Err(DeserializeError::custom("Signature missing fields".to_string())),
            }
        } else {
            Err(DeserializeError::custom("Role was not an object"))
        }
    }
}

/// A cryptographic signature.
#[derive(Clone, PartialEq, Debug)]
pub struct Signature {
    pub key_id: KeyId,
    pub method: SignatureScheme,
    pub sig: SignatureValue,
}

impl<'de> Deserialize<'de> for Signature {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::Object(mut object) = Deserialize::deserialize(de)? {
            match (object.remove("keyid"), object.remove("method"), object.remove("sig")) {
                (Some(k), Some(m), Some(s)) => {
                    let key_id =
                        json::from_value(k).map_err(|e| {
                                DeserializeError::custom(format!("Failed at keyid: {}", e))
                            })?;
                    let method =
                        json::from_value(m).map_err(|e| {
                                DeserializeError::custom(format!("Failed at method: {}", e))
                            })?;
                    let sig = json::from_value(s)
                        .map_err(|e| DeserializeError::custom(format!("Failed at sig: {}", e)))?;

                    Ok(Signature {
                        key_id: key_id,
                        method: method,
                        sig: sig,
                    })
                }
                _ => Err(DeserializeError::custom("Signature missing fields".to_string())),
            }
        } else {
            Err(DeserializeError::custom("Signature was not an object".to_string()))
        }
    }
}


/// A public key
#[derive(Clone, PartialEq, Debug, Deserialize)]
pub struct Key {
    #[serde(rename = "keytype")]
    pub typ: KeyType,
    #[serde(rename = "keyval")]
    pub value: KeyValue,
}

impl Key {
    pub fn verify(&self,
                  scheme: &SignatureScheme,
                  msg: &[u8],
                  sig: &SignatureValue)
                  -> Result<(), Error> {
        if self.typ.supports(scheme) {
            match self.typ {
                KeyType::Unsupported(ref s) => Err(Error::UnsupportedKeyType(s.clone())),
                _ => scheme.verify(&self.value, msg, sig),
            }
        } else {
            Err(Error::Generic(format!("Signature scheme mismatch: Key {:?}, Scheme {:?}",
                                       self,
                                       scheme)))
        }
    }
}

/// Types of public keys.
#[derive(Clone, PartialEq, Debug)]
pub enum KeyType {
    Ed25519,
    Unsupported(String),
}

impl KeyType {
    fn supports(&self, scheme: &SignatureScheme) -> bool {
        match (self, scheme) {
            (&KeyType::Ed25519, &SignatureScheme::Ed25519) => true,
            _ => false,
        }
    }
}

impl FromStr for KeyType {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "ed25519" => Ok(KeyType::Ed25519),
            typ => Ok(KeyType::Unsupported(typ.into())),
        }
    }
}

impl<'de> Deserialize<'de> for KeyType {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::String(ref s) = Deserialize::deserialize(de)? {
            s.parse().map_err(|_| unreachable!())
        } else {
            Err(DeserializeError::custom("Key type was not a string"))
        }
    }
}


/// The raw bytes of a public key.
#[derive(Clone, PartialEq, Debug)]
pub struct KeyValue(pub Vec<u8>);

impl KeyValue {
    /// Calculates the `KeyId` of the public key.
    pub fn key_id(&self) -> KeyId {
        // TODO this only works because we're using ed25519
        // and this will break when we add RSA.
        let key_value_hex = canonicalize(json!(HEXLOWER.encode(&self.0))).unwrap(); // TODO unwrap
        KeyId(HEXLOWER.encode(digest(&SHA256, &key_value_hex).as_ref()))
    }
}

impl<'de> Deserialize<'de> for KeyValue {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        match Deserialize::deserialize(de)? {
            json::Value::String(ref s) => {
                // TODO this is shit because we can't tell what type of key it is
                // e.g., ed25519 => hex, rsa => PEM
                // need to add this into the type/struct so it can be accessed here
                HEXLOWER.decode(s.as_ref())
                    .map(KeyValue)
                    .map_err(|e| DeserializeError::custom(format!("Key value was not hex: {}", e)))
            }
            json::Value::Object(mut object) => {
                json::from_value::<KeyValue>(object.remove("public")
                        .ok_or_else(|| DeserializeError::custom("Field 'public' missing"))?)
                    .map_err(|e| {
                        DeserializeError::custom(format!("Field 'public' not encoded correctly: \
                                                          {}",
                                                         e))
                    })
            }
            _ => Err(DeserializeError::custom("Key value was not a string or object")),
        }
    }
}


/// The hex encoded ID of a public key.
#[derive(Clone, Hash, Eq, PartialEq, Debug)]
pub struct KeyId(pub String);

impl<'de> Deserialize<'de> for KeyId {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        match Deserialize::deserialize(de)? {
            json::Value::String(s) => Ok(KeyId(s)),
            _ => Err(DeserializeError::custom("Key ID was not a string")),
        }
    }
}


#[derive(Clone, PartialEq, Debug)]
pub struct SignatureValue(Vec<u8>);

impl<'de> Deserialize<'de> for SignatureValue {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        match Deserialize::deserialize(de)? {
            json::Value::String(ref s) => {
                HEXLOWER.decode(s.as_ref())
                    .map(SignatureValue)
                    .map_err(|e| {
                        DeserializeError::custom(format!("Signature value was not hex: {}", e))
                    })
            }
            _ => Err(DeserializeError::custom("Signature value was not a string")),
        }
    }
}


#[derive(Clone, PartialEq, Debug)]
pub enum SignatureScheme {
    Ed25519,
    Unsupported(String),
}

impl SignatureScheme {
    fn verify(&self, pub_key: &KeyValue, msg: &[u8], sig: &SignatureValue) -> Result<(), Error> {
        match self {
            &SignatureScheme::Ed25519 => {
                ring::signature::verify(&ED25519,
                                        Input::from(&pub_key.0),
                                        Input::from(msg),
                                        Input::from(&sig.0))
                    .map_err(|_| Error::VerificationFailure("Bad signature".into()))
            }
            &SignatureScheme::Unsupported(ref s) => {
                Err(Error::UnsupportedSignatureScheme(s.clone()))
            }
        }
    }
}

impl FromStr for SignatureScheme {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "ed25519" => Ok(SignatureScheme::Ed25519),
            typ => Ok(SignatureScheme::Unsupported(typ.into())),
        }
    }
}

impl<'de> Deserialize<'de> for SignatureScheme {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::String(ref s) = Deserialize::deserialize(de)? {
            s.parse().map_err(|_| unreachable!())
        } else {
            Err(DeserializeError::custom("Key type was not a string"))
        }
    }
}


#[derive(Clone, PartialEq, Debug, Deserialize)]
pub struct MetadataMetadata {
    pub length: i64,
    pub hashes: HashMap<HashType, HashValue>,
    pub version: i32,
}


#[derive(Clone, PartialEq, Debug, Deserialize)]
pub struct SnapshotMetadataMetadata {
    pub length: Option<i64>,
    pub hashes: Option<HashMap<HashType, HashValue>>,
    pub version: i32,
}


#[derive(Clone, Hash, Eq, PartialEq, Debug)]
pub enum HashType {
    Sha256,
    Sha512,
    Unsupported(String),
}

impl HashType {
    pub fn preferences() -> &'static [HashType] {
        HASH_PREFERENCES
    }
}

impl FromStr for HashType {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "sha256" => Ok(HashType::Sha256),
            "sha512" => Ok(HashType::Sha512),
            typ => Ok(HashType::Unsupported(typ.into())),
        }
    }
}

impl<'de> Deserialize<'de> for HashType {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::String(ref s) = Deserialize::deserialize(de)? {
            s.parse().map_err(|_| unreachable!())
        } else {
            Err(DeserializeError::custom("Hash type was not a string"))
        }
    }
}


#[derive(Clone, PartialEq, Debug)]
pub struct HashValue(pub Vec<u8>);

impl<'de> Deserialize<'de> for HashValue {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        match Deserialize::deserialize(de)? {
            json::Value::String(ref s) => {
                HEXLOWER.decode(s.as_ref())
                    .map(HashValue)
                    .map_err(|e| DeserializeError::custom(format!("Hash value was not hex: {}", e)))
            }
            _ => Err(DeserializeError::custom("Hash value was not a string")),
        }
    }
}

#[derive(Clone, Debug, Deserialize)]
// TODO this is a dumb name
pub struct TargetInfo {
    pub length: i64,
    pub hashes: HashMap<HashType, HashValue>,
    pub custom: Option<HashMap<String, String>>, // TODO json value
}


#[derive(Clone, PartialEq, Debug, Deserialize)]
pub struct Delegations {
    keys: Vec<KeyId>,
    roles: Vec<DelegatedRole>,
}


#[derive(Clone, PartialEq, Debug, Deserialize)]
pub struct DelegatedRole {
    name: String,
    key_ids: Vec<KeyId>,
    threshold: i32,
    // TODO path_hash_prefixes
    paths: Vec<String>,
}
