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, 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 {
    fn matches(role: &Role) -> bool;
}

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

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

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

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

#[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 {
    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,
    /// 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,
            _ => 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)]
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))
        };
    }
}
