use chrono::{DateTime, UTC};
use data_encoding::HEXLOWER;
use json;
use pem;
use ring;
use ring::digest::{digest, SHA256};
use ring::signature::{ED25519, RSA_PSS_2048_8192_SHA256, RSA_PSS_2048_8192_SHA512};
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;
use rsa::convert_to_pkcs1;

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

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

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"),
            Role::TargetsDelegation(ref s) => write!(f, "{}", s),
        }
    }
}

pub trait RoleType: Debug + Clone{
    fn matches(role: &Role) -> bool;
}

#[derive(Debug, Clone)]
pub struct Root {}
impl RoleType for Root {
    fn matches(role: &Role) -> bool {
        match role {
            &Role::Root => true,
            _ => false,
        }
    }
}

#[derive(Debug, Clone)]
pub struct Targets {}
impl RoleType for Targets {
    fn matches(role: &Role) -> bool {
        match role {
            &Role::Targets => true,
            _ => false,
        }
    }
}

#[derive(Debug, Clone)]
pub struct Timestamp {}
impl RoleType for Timestamp {
    fn matches(role: &Role) -> bool {
        match role {
            &Role::Timestamp => true,
            _ => false,
        }
    }
}

#[derive(Debug, Clone)]
pub struct Snapshot {}
impl RoleType for Snapshot {
    fn matches(role: &Role) -> bool {
        match role {
            &Role::Snapshot => true,
            _ => false,
        }
    }
}

#[derive(Debug, Clone)]
pub struct SignedMetadata<R: RoleType + Clone> {
    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 {
    consistent_snapshot: bool,
    expires: DateTime<UTC>,
    pub version: i32,
    pub keys: HashMap<KeyId, Key>,
    pub root: RoleDefinition,
    pub targets: RoleDefinition,
    pub timestamp: RoleDefinition,
    pub snapshot: RoleDefinition,
}

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 consistent_snapshot = json::from_value(object.remove("consistent_snapshot")
                    .ok_or_else(|| DeserializeError::custom("Field 'consistent_snapshot' missing"))?).map_err(|e| {
                    DeserializeError::custom(format!("Field 'consistent_snapshot' 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 {
                consistent_snapshot,
                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, Clone)]
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 {
    /// The type of keys.
    #[serde(rename = "keytype")]
    pub typ: KeyType,
    /// The key's value.
    #[serde(rename = "keyval")]
    pub value: KeyValue,
}

impl Key {
    /// Use the given key to verify a signature over a byte array.
    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](https://en.wikipedia.org/wiki/EdDSA#Ed25519) signature scheme.
    Ed25519,
    /// [RSA](https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29)
    Rsa,
    /// Internal representation of an unsupported key type.
    Unsupported(String),
}

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

impl FromStr for KeyType {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "ed25519" => Ok(KeyType::Ed25519),
            "rsa" => Ok(KeyType::Rsa),
            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 {
    /// The key's raw bytes.
    pub value: Vec<u8>,
    /// The key's original value, needed for ID calculation
    pub original: String,
    /// The key's type,
    pub typ: KeyType,
}

impl KeyValue {
    /// Calculates the `KeyId` of the public key.
    pub fn key_id(&self) -> KeyId {
        match self.typ {
            KeyType::Unsupported(_) => KeyId(String::from("error")), // TODO this feels wrong, but we check this everywhere else
            _ => {
                let key_value = canonicalize(&json::Value::String(self.original.clone())).unwrap(); // TODO unwrap
                KeyId(HEXLOWER.encode(digest(&SHA256, &key_value).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 pretty shaky
                if s.starts_with("-----") {
                    pem::parse(s)
                        .map(|p| {
                            KeyValue {
                                value: p.contents,
                                original: s.clone(),
                                typ: KeyType::Rsa,
                            }
                        })
                        .map_err(|e| {
                            DeserializeError::custom(format!("Key was not PEM encoded: {}", e))
                        })
                } else {
                    HEXLOWER.decode(s.as_ref())
                        .map(|v| {
                            KeyValue {
                                value: v,
                                original: s.clone(),
                                typ: KeyType::Ed25519,
                            }
                        })
                        .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,
    RsaSsaPssSha256,
    RsaSsaPssSha512,
    Unsupported(String),
}

impl SignatureScheme {
    fn verify(&self, pub_key: &KeyValue, msg: &[u8], sig: &SignatureValue) -> Result<(), Error> {
        let alg: &ring::signature::VerificationAlgorithm = match self {
            &SignatureScheme::Ed25519 => &ED25519,
            &SignatureScheme::RsaSsaPssSha256 => &RSA_PSS_2048_8192_SHA256,
            &SignatureScheme::RsaSsaPssSha512 => &RSA_PSS_2048_8192_SHA512,
            &SignatureScheme::Unsupported(ref s) => {
                return Err(Error::UnsupportedSignatureScheme(s.clone()));
            }
        };

        ring::signature::verify(alg, Input::from(&convert_to_pkcs1(&pub_key.value)),
                                Input::from(msg), Input::from(&sig.0))
            .map_err(|_| Error::VerificationFailure("Bad signature".into()))
    }
}

impl FromStr for SignatureScheme {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "ed25519" => Ok(SignatureScheme::Ed25519),
            "rsassa-pss-sha256" => Ok(SignatureScheme::RsaSsaPssSha256),
            "rsassa-pss-sha512" => Ok(SignatureScheme::RsaSsaPssSha512),
            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)]
pub struct TargetInfo {
    pub length: i64,
    pub hashes: HashMap<HashType, HashValue>,
    pub custom: Option<HashMap<String, json::Value>>,
}


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


#[derive(Clone, PartialEq, Debug)]
pub struct DelegatedRole {
    pub name: String,
    pub key_ids: Vec<KeyId>,
    pub threshold: i32,
    pub terminating: bool,
    paths: TargetPaths,
}

impl DelegatedRole {
    pub fn could_have_target(&self, target: &str) -> bool {
        match self.paths {
            TargetPaths::Patterns(ref patterns) => {
                for path in patterns.iter() {
                    let path_str = path.as_str();
                    if path_str == target {
                        return true
                    } else if path_str.ends_with("/") && target.starts_with(path_str) {
                         return true
                    }
                }
                return false
            }
        }
    }
}

impl<'de> Deserialize<'de> for DelegatedRole {
    fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
        if let json::Value::Object(mut object) = Deserialize::deserialize(de)? {
            match (object.remove("name"), object.remove("keyids"),
                   object.remove("threshold"), object.remove("terminating"),
                   object.remove("paths"), object.remove("path_hash_prefixes")) {
                (Some(n), Some(ks), Some(t), Some(term), Some(ps), None) => {
                    let name =
                        json::from_value(n).map_err(|e| {
                                DeserializeError::custom(format!("Failed at name: {}", e))
                            })?;

                    let key_ids =
                        json::from_value(ks).map_err(|e| {
                                DeserializeError::custom(format!("Failed at keyids: {}", e))
                            })?;

                    let threshold =
                        json::from_value(t).map_err(|e| {
                                DeserializeError::custom(format!("Failed at treshold: {}", e))
                            })?;

                    let terminating =
                        json::from_value(term).map_err(|e| {
                                DeserializeError::custom(format!("Failed at treshold: {}", e))
                            })?;

                    let paths: Vec<String> =
                        json::from_value(ps).map_err(|e| {
                                DeserializeError::custom(format!("Failed at treshold: {}", e))
                            })?;

                    Ok(DelegatedRole {
                        name: name,
                        key_ids: key_ids,
                        threshold: threshold,
                        terminating: terminating,
                        paths: TargetPaths::Patterns(paths),
                    })
                }
                (_, _, _, _, Some(_), Some(_)) =>
                    Err(DeserializeError::custom("Fields 'paths' or 'pash_hash_prefixes' are mutually exclusive".to_string())),
                (_, _, _, _, _, Some(_)) =>
                    Err(DeserializeError::custom("'pash_hash_prefixes' is not yet supported".to_string())),
                _ => Err(DeserializeError::custom("Signature missing fields".to_string())),
            }
        } else {
            Err(DeserializeError::custom("Delegated role was not an object".to_string()))
        }
    }
}


#[derive(Clone, PartialEq, Debug)]
pub enum TargetPaths {
    Patterns(Vec<String>),
    // TODO HashPrefixes(Vec<String>),
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn delegated_role_could_have_target() {
        let vectors = vec![
            ("foo", "foo", true),
            ("foo/", "foo/bar", true),
            ("foo", "foo/bar", false),
            ("foo/bar", "foo/baz", false),
            ("foo/bar/", "foo/bar/baz", true),
        ];

        for &(prefix, target, success) in vectors.iter() {
            let delegation = DelegatedRole {
                name: "".to_string(),
                key_ids: Vec::new(),
                threshold: 1,
                terminating: false,
                paths: TargetPaths::Patterns(vec![prefix.to_string()]),
            };

            assert!(!success ^ delegation.could_have_target(target),
                    format!("Prefix {} should have target {}: {}", prefix, target, success))
        };
    }
}
