//! TUF metadata.

use chrono::offset::Utc;
use chrono::{DateTime, Duration};
use futures_io::AsyncRead;
use serde::de::{Deserialize, DeserializeOwned, Deserializer, Error as DeserializeError};
use serde::ser::{Error as SerializeError, Serialize, Serializer};
use serde_derive::{Deserialize, Serialize};
use std::borrow::Borrow;
use std::collections::{HashMap, HashSet};
use std::fmt::{self, Debug, Display};
use std::marker::PhantomData;
use std::str;

use crate::crypto::{self, HashAlgorithm, HashValue, KeyId, PrivateKey, PublicKey, Signature};
use crate::error::Error;
use crate::interchange::cjson::shims;
use crate::interchange::DataInterchange;
use crate::Result;

#[rustfmt::skip]
static PATH_ILLEGAL_COMPONENTS: &[&str] = &[
    ".", // current dir
    "..", // parent dir
         // TODO ? "0", // may translate to nul in windows
];

#[rustfmt::skip]
static PATH_ILLEGAL_COMPONENTS_CASE_INSENSITIVE: &[&str] = &[
    // DOS device files
    "CON",
    "PRN",
    "AUX",
    "NUL",
    "COM1",
    "COM2",
    "COM3",
    "COM4",
    "COM5",
    "COM6",
    "COM7",
    "COM8",
    "COM9",
    "LPT1",
    "LPT2",
    "LPT3",
    "LPT4",
    "LPT5",
    "LPT6",
    "LPT7",
    "LPT8",
    "LPT9",
    "KEYBD$",
    "CLOCK$",
    "SCREEN$",
    "$IDLE$",
    "CONFIG$",
];

#[rustfmt::skip]
static PATH_ILLEGAL_STRINGS: &[&str] = &[
    ":", // for *nix compatibility
    "\\", // for windows compatibility
    "<",
    ">",
    "\"",
    "|",
    "?",
    "*",
    // control characters, all illegal in FAT
    "\u{000}",
    "\u{001}",
    "\u{002}",
    "\u{003}",
    "\u{004}",
    "\u{005}",
    "\u{006}",
    "\u{007}",
    "\u{008}",
    "\u{009}",
    "\u{00a}",
    "\u{00b}",
    "\u{00c}",
    "\u{00d}",
    "\u{00e}",
    "\u{00f}",
    "\u{010}",
    "\u{011}",
    "\u{012}",
    "\u{013}",
    "\u{014}",
    "\u{015}",
    "\u{016}",
    "\u{017}",
    "\u{018}",
    "\u{019}",
    "\u{01a}",
    "\u{01b}",
    "\u{01c}",
    "\u{01d}",
    "\u{01e}",
    "\u{01f}",
    "\u{07f}",
];

fn safe_path(path: &str) -> Result<()> {
    if path.is_empty() {
        return Err(Error::IllegalArgument("Path cannot be empty".into()));
    }

    if path.starts_with('/') {
        return Err(Error::IllegalArgument("Cannot start with '/'".into()));
    }

    for bad_str in PATH_ILLEGAL_STRINGS {
        if path.contains(bad_str) {
            return Err(Error::IllegalArgument(format!(
                "Path cannot contain {:?}",
                bad_str
            )));
        }
    }

    for component in path.split('/') {
        for bad_str in PATH_ILLEGAL_COMPONENTS {
            if component == *bad_str {
                return Err(Error::IllegalArgument(format!(
                    "Path cannot have component {:?}",
                    component
                )));
            }
        }

        let component_lower = component.to_lowercase();
        for bad_str in PATH_ILLEGAL_COMPONENTS_CASE_INSENSITIVE {
            if component_lower.as_str() == *bad_str {
                return Err(Error::IllegalArgument(format!(
                    "Path cannot have component {:?}",
                    component
                )));
            }
        }
    }

    Ok(())
}

/// The TUF role.
#[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Role {
    /// The root role.
    #[serde(rename = "root")]
    Root,
    /// The snapshot role.
    #[serde(rename = "snapshot")]
    Snapshot,
    /// The targets role.
    #[serde(rename = "targets")]
    Targets,
    /// The timestamp role.
    #[serde(rename = "timestamp")]
    Timestamp,
}

impl Role {
    /// Check if this role could be associated with a given path.
    ///
    /// ```
    /// use tuf::metadata::{MetadataPath, Role};
    ///
    /// assert!(Role::Root.fuzzy_matches_path(&MetadataPath::from_role(&Role::Root)));
    /// assert!(Role::Snapshot.fuzzy_matches_path(&MetadataPath::from_role(&Role::Snapshot)));
    /// assert!(Role::Targets.fuzzy_matches_path(&MetadataPath::from_role(&Role::Targets)));
    /// assert!(Role::Timestamp.fuzzy_matches_path(&MetadataPath::from_role(&Role::Timestamp)));
    ///
    /// assert!(!Role::Root.fuzzy_matches_path(&MetadataPath::from_role(&Role::Snapshot)));
    /// assert!(!Role::Root.fuzzy_matches_path(&MetadataPath::new("wat").unwrap()));
    /// ```
    pub fn fuzzy_matches_path(&self, path: &MetadataPath) -> bool {
        match *self {
            Role::Root if &path.0 == "root" => true,
            Role::Snapshot if &path.0 == "snapshot" => true,
            Role::Timestamp if &path.0 == "timestamp" => true,
            Role::Targets if &path.0 == "targets" => true,
            Role::Targets if !&["root", "snapshot", "targets"].contains(&path.0.as_str()) => true,
            _ => false,
        }
    }

    /// Return the name of the role.
    pub fn name(&self) -> &'static str {
        match *self {
            Role::Root => "root",
            Role::Snapshot => "snapshot",
            Role::Targets => "targets",
            Role::Timestamp => "timestamp",
        }
    }
}

impl Display for Role {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.name())
    }
}

/// Enum used for addressing versioned TUF metadata.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash)]
pub enum MetadataVersion {
    /// The metadata is unversioned. This is the latest version of the metadata.
    None,
    /// The metadata is addressed by a specific version number.
    Number(u32),
}

impl MetadataVersion {
    /// Converts this struct into the string used for addressing metadata.
    pub fn prefix(&self) -> String {
        match *self {
            MetadataVersion::None => String::new(),
            MetadataVersion::Number(ref x) => format!("{}.", x),
        }
    }
}

/// Top level trait used for role metadata.
pub trait Metadata: Debug + PartialEq + Serialize + DeserializeOwned {
    /// The role associated with the metadata.
    const ROLE: Role;

    /// The version number.
    fn version(&self) -> u32;

    /// An immutable reference to the metadata's expiration `DateTime`.
    fn expires(&self) -> &DateTime<Utc>;
}

/// Unverified raw metadata with attached signatures and type information identifying the
/// metadata's type and serialization format.
#[derive(Debug, Clone, PartialEq)]
pub struct RawSignedMetadata<D, M> {
    bytes: Vec<u8>,
    _marker: PhantomData<(D, M)>,
}

impl<D, M> RawSignedMetadata<D, M>
where
    D: DataInterchange,
    M: Metadata,
{
    /// Create a new [`RawSignedMetadata`] using the provided `bytes`.
    pub fn new(bytes: Vec<u8>) -> Self {
        Self {
            bytes,
            _marker: PhantomData,
        }
    }

    /// Access this metadata's inner raw bytes.
    pub fn as_bytes(&self) -> &[u8] {
        &self.bytes
    }

    /// Parse this metadata.
    ///
    /// **WARNING**: This does not verify signatures, so it exposes users to potential parser
    /// exploits.
    pub fn parse_untrusted(&self) -> Result<SignedMetadata<D, M>> {
        D::from_slice(&self.bytes)
    }
}

/// A collection of [RawSignedMetadata] that describes the metadata at one
/// commit.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct RawSignedMetadataSet<D> {
    root: Option<RawSignedMetadata<D, RootMetadata>>,
    targets: Option<RawSignedMetadata<D, TargetsMetadata>>,
    snapshot: Option<RawSignedMetadata<D, SnapshotMetadata>>,
    timestamp: Option<RawSignedMetadata<D, TimestampMetadata>>,
}

impl<D> RawSignedMetadataSet<D> {
    /// Returns a reference to the built root metadata, if any.
    pub fn root(&self) -> Option<&RawSignedMetadata<D, RootMetadata>> {
        self.root.as_ref()
    }

    /// Returns a reference to the built targets metadata, if any.
    pub fn targets(&self) -> Option<&RawSignedMetadata<D, TargetsMetadata>> {
        self.targets.as_ref()
    }

    /// Returns a reference to the built snapshot metadata, if any.
    pub fn snapshot(&self) -> Option<&RawSignedMetadata<D, SnapshotMetadata>> {
        self.snapshot.as_ref()
    }

    /// Returns a reference to the built timestamp metadata, if any.
    pub fn timestamp(&self) -> Option<&RawSignedMetadata<D, TimestampMetadata>> {
        self.timestamp.as_ref()
    }
}

/// Builder for [RawSignedMetadataSet].
#[derive(Default)]
pub struct RawSignedMetadataSetBuilder<D>
where
    D: DataInterchange,
{
    metadata: RawSignedMetadataSet<D>,
}

impl<D> RawSignedMetadataSetBuilder<D>
where
    D: DataInterchange,
{
    /// Create a new [RawSignedMetadataSetBuilder].
    pub fn new() -> Self {
        Self {
            metadata: RawSignedMetadataSet {
                root: None,
                targets: None,
                snapshot: None,
                timestamp: None,
            },
        }
    }

    /// Set or replace the root metadata.
    pub fn root(mut self, root: RawSignedMetadata<D, RootMetadata>) -> Self {
        self.metadata.root = Some(root);
        self
    }

    /// Set or replace the targets metadata.
    pub fn targets(mut self, targets: RawSignedMetadata<D, TargetsMetadata>) -> Self {
        self.metadata.targets = Some(targets);
        self
    }

    /// Set or replace the snapshot metadata.
    pub fn snapshot(mut self, snapshot: RawSignedMetadata<D, SnapshotMetadata>) -> Self {
        self.metadata.snapshot = Some(snapshot);
        self
    }

    /// Set or replace the timestamp metadata.
    pub fn timestamp(mut self, timestamp: RawSignedMetadata<D, TimestampMetadata>) -> Self {
        self.metadata.timestamp = Some(timestamp);
        self
    }

    /// Return a [RawSignedMetadataSet].
    pub fn build(self) -> RawSignedMetadataSet<D> {
        self.metadata
    }
}

/// Helper to construct `SignedMetadata`.
#[derive(Debug, Clone)]
pub struct SignedMetadataBuilder<D, M>
where
    D: DataInterchange,
{
    signatures: HashMap<KeyId, Signature>,
    metadata: D::RawData,
    metadata_bytes: Vec<u8>,
    _marker: PhantomData<M>,
}

impl<D, M> SignedMetadataBuilder<D, M>
where
    D: DataInterchange,
    M: Metadata,
{
    /// Create a new `SignedMetadataBuilder` from a given `Metadata`.
    pub fn from_metadata(metadata: &M) -> Result<Self> {
        let metadata = D::serialize(metadata)?;
        Self::from_raw_metadata(metadata)
    }

    /// Create a new `SignedMetadataBuilder` from manually serialized metadata to be signed.
    /// Returns an error if `metadata` cannot be parsed into `M`.
    pub fn from_raw_metadata(metadata: D::RawData) -> Result<Self> {
        let _ensure_metadata_parses: M = D::deserialize(&metadata)?;
        let metadata_bytes = D::canonicalize(&metadata)?;
        Ok(Self {
            signatures: HashMap::new(),
            metadata,
            metadata_bytes,
            _marker: PhantomData,
        })
    }

    /// Sign the metadata using the given `private_key`, replacing any existing signatures with the
    /// same `KeyId`.
    ///
    /// **WARNING**: You should never have multiple TUF private keys on the same machine, so if
    /// you're using this to append several signatures at once, you are doing something wrong. The
    /// preferred method is to generate your copy of the metadata locally and use
    /// `SignedMetadata::merge_signatures` to perform the "append" operations.
    pub fn sign(mut self, private_key: &dyn PrivateKey) -> Result<Self> {
        let sig = private_key.sign(&self.metadata_bytes)?;
        let _ = self.signatures.insert(sig.key_id().clone(), sig);
        Ok(self)
    }

    /// Construct a new `SignedMetadata` using the included signatures, sorting the signatures by
    /// `KeyId`.
    pub fn build(self) -> SignedMetadata<D, M> {
        let mut signatures = self
            .signatures
            .into_iter()
            .map(|(_k, v)| v)
            .collect::<Vec<_>>();
        signatures.sort_unstable_by(|a, b| a.key_id().cmp(b.key_id()));

        SignedMetadata {
            signatures,
            metadata: self.metadata,
            _marker: PhantomData,
        }
    }
}

/// Serialized metadata with attached unverified signatures.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SignedMetadata<D, M>
where
    D: DataInterchange,
{
    signatures: Vec<Signature>,
    #[serde(rename = "signed")]
    metadata: D::RawData,
    #[serde(skip_serializing, skip_deserializing)]
    _marker: PhantomData<M>,
}

impl<D, M> SignedMetadata<D, M>
where
    D: DataInterchange,
    M: Metadata,
{
    /// Create a new `SignedMetadata`. The supplied private key is used to sign the canonicalized
    /// bytes of the provided metadata with the provided scheme.
    ///
    /// ```
    /// # use chrono::prelude::*;
    /// # use tuf::crypto::{Ed25519PrivateKey, PrivateKey, SignatureScheme, HashAlgorithm};
    /// # use tuf::interchange::Json;
    /// # use tuf::metadata::{SignedMetadata, SnapshotMetadataBuilder};
    /// #
    /// # let key: &[u8] = include_bytes!("../tests/ed25519/ed25519-1.pk8.der");
    /// let key = Ed25519PrivateKey::from_pkcs8(&key).unwrap();
    ///
    /// let snapshot = SnapshotMetadataBuilder::new().build().unwrap();
    /// SignedMetadata::<Json, _>::new(&snapshot, &key).unwrap();
    /// ```
    pub fn new(metadata: &M, private_key: &dyn PrivateKey) -> Result<Self> {
        let raw = D::serialize(metadata)?;
        let bytes = D::canonicalize(&raw)?;
        let sig = private_key.sign(&bytes)?;
        Ok(Self {
            signatures: vec![sig],
            metadata: raw,
            _marker: PhantomData,
        })
    }

    /// Serialize this metadata to canonical bytes suitable for serialization. Note that this
    /// method is only intended to serialize signed metadata generated by this crate, not to
    /// re-serialize metadata that was originally obtained from a remote source.
    ///
    /// TUF metadata hashes are on the raw bytes of the metadata, so it is not guaranteed that the
    /// hash of the returned bytes will match a hash included in, for example, a snapshot metadata
    /// file, as:
    /// * Parsing metadata removes unknown fields, which would not be included in the returned
    /// bytes,
    /// * DataInterchange implementations only guarantee the bytes are canonical for the purpose of
    /// a signature. Metadata obtained from a remote source may have included different whitespace
    /// or ordered fields in a way that is not preserved when parsing that metadata.
    pub fn to_raw(&self) -> Result<RawSignedMetadata<D, M>> {
        let bytes = D::canonicalize(&D::serialize(self)?)?;
        Ok(RawSignedMetadata::new(bytes))
    }

    /// Append a signature to this signed metadata. Will overwrite signature by keys with the same
    /// ID.
    ///
    /// **WARNING**: You should never have multiple TUF private keys on the same machine, so if
    /// you're using this to append several signatures at once, you are doing something wrong. The
    /// preferred method is to generate your copy of the metadata locally and use `merge_signatures`
    /// to perform the "append" operations.
    ///
    /// ```
    /// # use chrono::prelude::*;
    /// # use tuf::crypto::{Ed25519PrivateKey, PrivateKey, SignatureScheme, HashAlgorithm};
    /// # use tuf::interchange::Json;
    /// # use tuf::metadata::{SignedMetadata, SnapshotMetadataBuilder};
    /// #
    /// let key_1: &[u8] = include_bytes!("../tests/ed25519/ed25519-1.pk8.der");
    /// let key_1 = Ed25519PrivateKey::from_pkcs8(&key_1).unwrap();
    ///
    /// // Note: This is for demonstration purposes only.
    /// // You should never have multiple private keys on the same device.
    /// let key_2: &[u8] = include_bytes!("../tests/ed25519/ed25519-2.pk8.der");
    /// let key_2 = Ed25519PrivateKey::from_pkcs8(&key_2).unwrap();
    ///
    /// let snapshot = SnapshotMetadataBuilder::new().build().unwrap();
    /// let mut snapshot = SignedMetadata::<Json, _>::new(&snapshot, &key_1).unwrap();
    ///
    /// snapshot.add_signature(&key_2).unwrap();
    /// assert_eq!(snapshot.signatures().len(), 2);
    ///
    /// snapshot.add_signature(&key_2).unwrap();
    /// assert_eq!(snapshot.signatures().len(), 2);
    /// ```
    pub fn add_signature(&mut self, private_key: &dyn PrivateKey) -> Result<()> {
        let bytes = D::canonicalize(&self.metadata)?;
        let sig = private_key.sign(&bytes)?;
        self.signatures
            .retain(|s| s.key_id() != private_key.public().key_id());
        self.signatures.push(sig);
        self.signatures.sort();
        Ok(())
    }

    /// Merge the singatures from `other` into `self` if and only if
    /// `self.as_ref() == other.as_ref()`. If `self` and `other` contain signatures from the same
    /// key ID, then the signatures from `self` will replace the signatures from `other`.
    pub fn merge_signatures(&mut self, other: &Self) -> Result<()> {
        if self.metadata != other.metadata {
            return Err(Error::IllegalArgument(
                "Attempted to merge unequal metadata".into(),
            ));
        }

        let key_ids = self
            .signatures
            .iter()
            .map(|s| s.key_id().clone())
            .collect::<HashSet<KeyId>>();

        self.signatures.extend(
            other
                .signatures
                .iter()
                .filter(|s| !key_ids.contains(s.key_id()))
                .cloned(),
        );
        self.signatures.sort();

        Ok(())
    }

    /// An immutable reference to the signatures.
    pub fn signatures(&self) -> &[Signature] {
        &self.signatures
    }

    /// Parse the version number of this metadata without verifying signatures.
    ///
    /// This operation is generally unsafe to do with metadata obtained from an untrusted source,
    /// but rolling forward to the most recent root.json requires using the version number of the
    /// latest root.json.
    pub(crate) fn parse_version_untrusted(&self) -> Result<u32> {
        #[derive(Deserialize)]
        pub struct MetadataVersion {
            version: u32,
        }

        let meta: MetadataVersion = D::deserialize(&self.metadata)?;
        Ok(meta.version)
    }

    /// Parse this metadata without verifying signatures.
    ///
    /// This operation is not safe to do with metadata obtained from an untrusted source.
    pub fn assume_valid(&self) -> Result<M> {
        D::deserialize(&self.metadata)
    }
}

/// Helper to construct `RootMetadata`.
pub struct RootMetadataBuilder {
    version: u32,
    expires: DateTime<Utc>,
    consistent_snapshot: bool,
    keys: HashMap<KeyId, PublicKey>,
    root_threshold: u32,
    root_key_ids: Vec<KeyId>,
    snapshot_threshold: u32,
    snapshot_key_ids: Vec<KeyId>,
    targets_threshold: u32,
    targets_key_ids: Vec<KeyId>,
    timestamp_threshold: u32,
    timestamp_key_ids: Vec<KeyId>,
}

impl RootMetadataBuilder {
    /// Create a new `RootMetadataBuilder`. It defaults to:
    ///
    /// * version: 1,
    /// * expires: 365 days from the current time.
    /// * consistent snapshot: true
    /// * role thresholds: 1
    pub fn new() -> Self {
        RootMetadataBuilder {
            version: 1,
            expires: Utc::now() + Duration::days(365),
            consistent_snapshot: true,
            keys: HashMap::new(),
            root_threshold: 1,
            root_key_ids: Vec::new(),
            snapshot_threshold: 1,
            snapshot_key_ids: Vec::new(),
            targets_threshold: 1,
            targets_key_ids: Vec::new(),
            timestamp_threshold: 1,
            timestamp_key_ids: Vec::new(),
        }
    }

    /// Set the version number for this metadata.
    pub fn version(mut self, version: u32) -> Self {
        self.version = version;
        self
    }

    /// Set the time this metadata expires.
    pub fn expires(mut self, expires: DateTime<Utc>) -> Self {
        self.expires = expires;
        self
    }

    /// Set this metadata to have a consistent snapshot.
    pub fn consistent_snapshot(mut self, consistent_snapshot: bool) -> Self {
        self.consistent_snapshot = consistent_snapshot;
        self
    }

    /// Set the root threshold.
    pub fn root_threshold(mut self, threshold: u32) -> Self {
        self.root_threshold = threshold;
        self
    }

    /// Add a root public key.
    pub fn root_key(mut self, public_key: PublicKey) -> Self {
        let key_id = public_key.key_id().clone();
        self.keys.insert(key_id.clone(), public_key);
        self.root_key_ids.push(key_id);
        self
    }

    /// Set the snapshot threshold.
    pub fn snapshot_threshold(mut self, threshold: u32) -> Self {
        self.snapshot_threshold = threshold;
        self
    }

    /// Add a snapshot public key.
    pub fn snapshot_key(mut self, public_key: PublicKey) -> Self {
        let key_id = public_key.key_id().clone();
        self.keys.insert(key_id.clone(), public_key);
        self.snapshot_key_ids.push(key_id);
        self
    }

    /// Set the targets threshold.
    pub fn targets_threshold(mut self, threshold: u32) -> Self {
        self.targets_threshold = threshold;
        self
    }

    /// Add a targets public key.
    pub fn targets_key(mut self, public_key: PublicKey) -> Self {
        let key_id = public_key.key_id().clone();
        self.keys.insert(key_id.clone(), public_key);
        self.targets_key_ids.push(key_id);
        self
    }

    /// Set the timestamp threshold.
    pub fn timestamp_threshold(mut self, threshold: u32) -> Self {
        self.timestamp_threshold = threshold;
        self
    }

    /// Add a timestamp public key.
    pub fn timestamp_key(mut self, public_key: PublicKey) -> Self {
        let key_id = public_key.key_id().clone();
        self.keys.insert(key_id.clone(), public_key);
        self.timestamp_key_ids.push(key_id);
        self
    }

    /// Construct a new `RootMetadata`.
    pub fn build(self) -> Result<RootMetadata> {
        RootMetadata::new(
            self.version,
            self.expires,
            self.consistent_snapshot,
            self.keys,
            RoleDefinition::new(self.root_threshold, self.root_key_ids)?,
            RoleDefinition::new(self.snapshot_threshold, self.snapshot_key_ids)?,
            RoleDefinition::new(self.targets_threshold, self.targets_key_ids)?,
            RoleDefinition::new(self.timestamp_threshold, self.timestamp_key_ids)?,
        )
    }

    /// Construct a new `SignedMetadata<D, RootMetadata>`.
    pub fn signed<D>(self, private_key: &dyn PrivateKey) -> Result<SignedMetadata<D, RootMetadata>>
    where
        D: DataInterchange,
    {
        SignedMetadata::new(&self.build()?, private_key)
    }
}

impl Default for RootMetadataBuilder {
    fn default() -> Self {
        RootMetadataBuilder::new()
    }
}

impl From<RootMetadata> for RootMetadataBuilder {
    fn from(metadata: RootMetadata) -> Self {
        RootMetadataBuilder {
            version: metadata.version,
            expires: metadata.expires,
            consistent_snapshot: metadata.consistent_snapshot,
            keys: metadata.keys,
            root_threshold: metadata.root.threshold,
            root_key_ids: metadata.root.key_ids,
            snapshot_threshold: metadata.snapshot.threshold,
            snapshot_key_ids: metadata.snapshot.key_ids,
            targets_threshold: metadata.targets.threshold,
            targets_key_ids: metadata.targets.key_ids,
            timestamp_threshold: metadata.timestamp.threshold,
            timestamp_key_ids: metadata.timestamp.key_ids,
        }
    }
}

/// Metadata for the root role.
#[derive(Debug, Clone, PartialEq)]
pub struct RootMetadata {
    version: u32,
    expires: DateTime<Utc>,
    consistent_snapshot: bool,
    keys: HashMap<KeyId, PublicKey>,
    root: RoleDefinition,
    snapshot: RoleDefinition,
    targets: RoleDefinition,
    timestamp: RoleDefinition,
}

impl RootMetadata {
    /// Create new `RootMetadata`.
    pub fn new(
        version: u32,
        expires: DateTime<Utc>,
        consistent_snapshot: bool,
        keys: HashMap<KeyId, PublicKey>,
        root: RoleDefinition,
        snapshot: RoleDefinition,
        targets: RoleDefinition,
        timestamp: RoleDefinition,
    ) -> Result<Self> {
        if version < 1 {
            return Err(Error::IllegalArgument(format!(
                "Metadata version must be greater than zero. Found: {}",
                version
            )));
        }

        Ok(RootMetadata {
            version,
            expires,
            consistent_snapshot,
            keys,
            root,
            snapshot,
            targets,
            timestamp,
        })
    }

    /// Whether or not this repository is currently implementing that TUF consistent snapshot
    /// feature.
    pub fn consistent_snapshot(&self) -> bool {
        self.consistent_snapshot
    }

    /// An immutable reference to the map of trusted keys.
    pub fn keys(&self) -> &HashMap<KeyId, PublicKey> {
        &self.keys
    }

    /// An iterator over all the trusted root public keys.
    pub fn root_keys(&self) -> impl Iterator<Item = &PublicKey> {
        self.keys().iter().filter_map(move |(k, v)| {
            if self.root.key_ids().contains(k) {
                Some(v)
            } else {
                None
            }
        })
    }

    /// An iterator over all the trusted snapshot public keys.
    pub fn snapshot_keys(&self) -> impl Iterator<Item = &PublicKey> {
        self.keys().iter().filter_map(move |(k, v)| {
            if self.snapshot.key_ids().contains(k) {
                Some(v)
            } else {
                None
            }
        })
    }

    /// An iterator over all the trusted targets public keys.
    pub fn targets_keys(&self) -> impl Iterator<Item = &PublicKey> {
        self.keys().iter().filter_map(move |(k, v)| {
            if self.targets.key_ids().contains(k) {
                Some(v)
            } else {
                None
            }
        })
    }

    /// An iterator over all the trusted timestamp public keys.
    pub fn timestamp_keys(&self) -> impl Iterator<Item = &PublicKey> {
        self.keys().iter().filter_map(move |(k, v)| {
            if self.timestamp.key_ids().contains(k) {
                Some(v)
            } else {
                None
            }
        })
    }

    /// An immutable reference to the root role's definition.
    pub fn root(&self) -> &RoleDefinition {
        &self.root
    }

    /// An immutable reference to the snapshot role's definition.
    pub fn snapshot(&self) -> &RoleDefinition {
        &self.snapshot
    }

    /// An immutable reference to the targets role's definition.
    pub fn targets(&self) -> &RoleDefinition {
        &self.targets
    }

    /// An immutable reference to the timestamp role's definition.
    pub fn timestamp(&self) -> &RoleDefinition {
        &self.timestamp
    }
}

impl Metadata for RootMetadata {
    const ROLE: Role = Role::Root;

    fn version(&self) -> u32 {
        self.version
    }

    fn expires(&self) -> &DateTime<Utc> {
        &self.expires
    }
}

impl Serialize for RootMetadata {
    fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let m = shims::RootMetadata::from(self)
            .map_err(|e| SerializeError::custom(format!("{:?}", e)))?;
        m.serialize(ser)
    }
}

impl<'de> Deserialize<'de> for RootMetadata {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let intermediate: shims::RootMetadata = Deserialize::deserialize(de)?;
        intermediate
            .try_into()
            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

/// The definition of what allows a role to be trusted.
#[derive(Clone, Debug, PartialEq)]
pub struct RoleDefinition {
    threshold: u32,
    key_ids: Vec<KeyId>,
}

impl RoleDefinition {
    /// Create a new `RoleDefinition` with a given threshold and set of authorized `KeyID`s.
    pub fn new(threshold: u32, key_ids: Vec<KeyId>) -> Result<Self> {
        if threshold < 1 {
            return Err(Error::IllegalArgument(format!("Threshold: {}", threshold)));
        }

        if key_ids.is_empty() {
            return Err(Error::IllegalArgument(
                "Cannot define a role with no associated key IDs".into(),
            ));
        }

        if (key_ids.len() as u64) < u64::from(threshold) {
            return Err(Error::IllegalArgument(format!(
                "Cannot have a threshold greater than the number of associated key IDs. {} vs. {}",
                threshold,
                key_ids.len()
            )));
        }

        Ok(RoleDefinition { threshold, key_ids })
    }

    /// The threshold number of signatures required for the role to be trusted.
    pub fn threshold(&self) -> u32 {
        self.threshold
    }

    /// An immutable reference to the set of `KeyID`s that are authorized to sign the role.
    pub fn key_ids(&self) -> &[KeyId] {
        &self.key_ids
    }
}

impl Serialize for RoleDefinition {
    fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        shims::RoleDefinition::from(self)
            .map_err(|e| SerializeError::custom(format!("{:?}", e)))?
            .serialize(ser)
    }
}

impl<'de> Deserialize<'de> for RoleDefinition {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let intermediate: shims::RoleDefinition = Deserialize::deserialize(de)?;
        intermediate
            .try_into()
            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

/// Wrapper for a path to metadata.
///
/// Note: This should **not** contain the file extension. This is automatically added by the
/// library depending on what type of data interchange format is being used.
///
/// ```
/// use tuf::metadata::MetadataPath;
///
/// // right
/// let _ = MetadataPath::new("root");
///
/// // wrong
/// let _ = MetadataPath::new("root.json");
/// ```
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
pub struct MetadataPath(String);

impl MetadataPath {
    /// Create a new `MetadataPath` from a `String`.
    ///
    /// ```
    /// # use tuf::metadata::MetadataPath;
    /// assert!(MetadataPath::new("foo").is_ok());
    /// assert!(MetadataPath::new("/foo").is_err());
    /// assert!(MetadataPath::new("../foo").is_err());
    /// assert!(MetadataPath::new("foo/..").is_err());
    /// assert!(MetadataPath::new("foo/../bar").is_err());
    /// assert!(MetadataPath::new("..foo").is_ok());
    /// assert!(MetadataPath::new("foo/..bar").is_ok());
    /// assert!(MetadataPath::new("foo/bar..").is_ok());
    /// ```
    pub fn new<P: Into<String>>(path: P) -> Result<Self> {
        let path = path.into();
        safe_path(&path)?;
        Ok(MetadataPath(path))
    }

    /// Create a metadata path from the given role.
    ///
    /// ```
    /// # use tuf::metadata::{Role, MetadataPath};
    /// assert_eq!(MetadataPath::from_role(&Role::Root),
    ///            MetadataPath::new("root").unwrap());
    /// assert_eq!(MetadataPath::from_role(&Role::Snapshot),
    ///            MetadataPath::new("snapshot").unwrap());
    /// assert_eq!(MetadataPath::from_role(&Role::Targets),
    ///            MetadataPath::new("targets").unwrap());
    /// assert_eq!(MetadataPath::from_role(&Role::Timestamp),
    ///            MetadataPath::new("timestamp").unwrap());
    /// ```
    pub fn from_role(role: &Role) -> Self {
        Self::new(format!("{}", role)).unwrap()
    }

    /// Split `MetadataPath` into components that can be joined to create URL paths, Unix paths, or
    /// Windows paths.
    ///
    /// ```
    /// # use tuf::crypto::HashValue;
    /// # use tuf::interchange::Json;
    /// # use tuf::metadata::{MetadataPath, MetadataVersion};
    /// #
    /// let path = MetadataPath::new("foo/bar").unwrap();
    /// assert_eq!(path.components::<Json>(MetadataVersion::None),
    ///            ["foo".to_string(), "bar.json".to_string()]);
    /// assert_eq!(path.components::<Json>(MetadataVersion::Number(1)),
    ///            ["foo".to_string(), "1.bar.json".to_string()]);
    /// ```
    pub fn components<D>(&self, version: MetadataVersion) -> Vec<String>
    where
        D: DataInterchange,
    {
        let mut buf: Vec<String> = self.0.split('/').map(|s| s.to_string()).collect();
        let len = buf.len();
        buf[len - 1] = format!("{}{}.{}", version.prefix(), buf[len - 1], D::extension());
        buf
    }
}

impl Display for MetadataPath {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.0)
    }
}

impl<'de> Deserialize<'de> for MetadataPath {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let s: String = Deserialize::deserialize(de)?;
        MetadataPath::new(s).map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

/// Helper to construct `TimestampMetadata`.
pub struct TimestampMetadataBuilder {
    version: u32,
    expires: DateTime<Utc>,
    snapshot: MetadataDescription,
}

impl TimestampMetadataBuilder {
    /// Create a new `TimestampMetadataBuilder` from a given snapshot. It defaults to:
    ///
    /// * version: 1
    /// * expires: 1 day from the current time.
    pub fn from_snapshot<D>(
        snapshot: &SignedMetadata<D, SnapshotMetadata>,
        hash_algs: &[HashAlgorithm],
    ) -> Result<Self>
    where
        D: DataInterchange,
    {
        let raw_snapshot = snapshot.to_raw()?;
        let description = MetadataDescription::from_slice(
            raw_snapshot.as_bytes(),
            snapshot.parse_version_untrusted()?,
            hash_algs,
        )?;

        Ok(Self::from_metadata_description(description))
    }

    /// Create a new `TimestampMetadataBuilder` from a given
    /// `MetadataDescription`. It defaults to:
    ///
    /// * version: 1
    /// * expires: 1 day from the current time.
    pub fn from_metadata_description(description: MetadataDescription) -> Self {
        TimestampMetadataBuilder {
            version: 1,
            expires: Utc::now() + Duration::days(1),
            snapshot: description,
        }
    }

    /// Set the version number for this metadata.
    pub fn version(mut self, version: u32) -> Self {
        self.version = version;
        self
    }

    /// Set the time this metadata expires.
    pub fn expires(mut self, expires: DateTime<Utc>) -> Self {
        self.expires = expires;
        self
    }

    /// Construct a new `TimestampMetadata`.
    pub fn build(self) -> Result<TimestampMetadata> {
        TimestampMetadata::new(self.version, self.expires, self.snapshot)
    }

    /// Construct a new `SignedMetadata<D, TimestampMetadata>`.
    pub fn signed<D>(
        self,
        private_key: &dyn PrivateKey,
    ) -> Result<SignedMetadata<D, TimestampMetadata>>
    where
        D: DataInterchange,
    {
        SignedMetadata::new(&self.build()?, private_key)
    }
}

/// Metadata for the timestamp role.
#[derive(Debug, Clone, PartialEq)]
pub struct TimestampMetadata {
    version: u32,
    expires: DateTime<Utc>,
    snapshot: MetadataDescription,
}

impl TimestampMetadata {
    /// Create new `TimestampMetadata`.
    pub fn new(
        version: u32,
        expires: DateTime<Utc>,
        snapshot: MetadataDescription,
    ) -> Result<Self> {
        if version < 1 {
            return Err(Error::IllegalArgument(format!(
                "Metadata version must be greater than zero. Found: {}",
                version
            )));
        }

        Ok(TimestampMetadata {
            version,
            expires,
            snapshot,
        })
    }

    /// An immutable reference to the snapshot description.
    pub fn snapshot(&self) -> &MetadataDescription {
        &self.snapshot
    }
}

impl Metadata for TimestampMetadata {
    const ROLE: Role = Role::Timestamp;

    fn version(&self) -> u32 {
        self.version
    }

    fn expires(&self) -> &DateTime<Utc> {
        &self.expires
    }
}

impl Serialize for TimestampMetadata {
    fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        shims::TimestampMetadata::from(self)
            .map_err(|e| SerializeError::custom(format!("{:?}", e)))?
            .serialize(ser)
    }
}

impl<'de> Deserialize<'de> for TimestampMetadata {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let intermediate: shims::TimestampMetadata = Deserialize::deserialize(de)?;
        intermediate
            .try_into()
            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

/// Description of a piece of metadata, used in verification.
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct MetadataDescription {
    version: u32,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    length: Option<usize>,
    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
    hashes: HashMap<HashAlgorithm, HashValue>,
}

impl MetadataDescription {
    /// Create a `MetadataDescription` from a slice. Size and hashes will be calculated.
    pub fn from_slice(buf: &[u8], version: u32, hash_algs: &[HashAlgorithm]) -> Result<Self> {
        if version < 1 {
            return Err(Error::IllegalArgument(
                "Version must be greater than zero".into(),
            ));
        }

        let hashes = if hash_algs.is_empty() {
            HashMap::new()
        } else {
            crypto::calculate_hashes_from_slice(buf, hash_algs)?
        };

        Ok(MetadataDescription {
            version,
            length: Some(buf.len()),
            hashes,
        })
    }

    /// Create a new `MetadataDescription`.
    pub fn new(
        version: u32,
        length: Option<usize>,
        hashes: HashMap<HashAlgorithm, HashValue>,
    ) -> Result<Self> {
        if version < 1 {
            return Err(Error::IllegalArgument(format!(
                "Metadata version must be greater than zero. Found: {}",
                version
            )));
        }

        Ok(MetadataDescription {
            version,
            length,
            hashes,
        })
    }

    /// The version of the described metadata.
    pub fn version(&self) -> u32 {
        self.version
    }

    /// The length of the described metadata.
    pub fn length(&self) -> Option<usize> {
        self.length
    }

    /// An immutable reference to the hashes of the described metadata.
    pub fn hashes(&self) -> &HashMap<HashAlgorithm, HashValue> {
        &self.hashes
    }
}

impl<'de> Deserialize<'de> for MetadataDescription {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let intermediate: shims::MetadataDescription = Deserialize::deserialize(de)?;
        intermediate
            .try_into()
            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

/// Helper to construct `SnapshotMetadata`.
pub struct SnapshotMetadataBuilder {
    version: u32,
    expires: DateTime<Utc>,
    meta: HashMap<MetadataPath, MetadataDescription>,
}

impl SnapshotMetadataBuilder {
    /// Create a new `SnapshotMetadataBuilder`. It defaults to:
    ///
    /// * version: 1
    /// * expires: 7 days from the current time.
    pub fn new() -> Self {
        SnapshotMetadataBuilder {
            version: 1,
            expires: Utc::now() + Duration::days(7),
            meta: HashMap::new(),
        }
    }

    /// Create a new [SnapshotMetadataBuilder] from a given snapshot. It defaults to:
    ///
    /// * version: 1
    /// * expires: 7 day from the current time.
    pub fn from_targets<D>(
        targets: &SignedMetadata<D, TargetsMetadata>,
        hash_algs: &[HashAlgorithm],
    ) -> Result<Self>
    where
        D: DataInterchange,
    {
        SnapshotMetadataBuilder::new().insert_metadata(targets, hash_algs)
    }

    /// Set the version number for this metadata.
    pub fn version(mut self, version: u32) -> Self {
        self.version = version;
        self
    }

    /// Set the time this metadata expires.
    pub fn expires(mut self, expires: DateTime<Utc>) -> Self {
        self.expires = expires;
        self
    }

    /// Add metadata to this snapshot metadata using the default path.
    pub fn insert_metadata<D, M>(
        self,
        metadata: &SignedMetadata<D, M>,
        hash_algs: &[HashAlgorithm],
    ) -> Result<Self>
    where
        M: Metadata,
        D: DataInterchange,
    {
        self.insert_metadata_with_path(M::ROLE.name(), metadata, hash_algs)
    }

    /// Add metadata to this snapshot metadata using a custom path.
    pub fn insert_metadata_with_path<P, D, M>(
        self,
        path: P,
        metadata: &SignedMetadata<D, M>,
        hash_algs: &[HashAlgorithm],
    ) -> Result<Self>
    where
        P: Into<String>,
        M: Metadata,
        D: DataInterchange,
    {
        let raw_metadata = metadata.to_raw()?;
        let description = MetadataDescription::from_slice(
            raw_metadata.as_bytes(),
            metadata.parse_version_untrusted()?,
            hash_algs,
        )?;
        let path = MetadataPath::new(path)?;
        Ok(self.insert_metadata_description(path, description))
    }

    /// Add `MetadataDescription` to this snapshot metadata using a custom path.
    pub fn insert_metadata_description(
        mut self,
        path: MetadataPath,
        description: MetadataDescription,
    ) -> Self {
        self.meta.insert(path, description);
        self
    }

    /// Construct a new `SnapshotMetadata`.
    pub fn build(self) -> Result<SnapshotMetadata> {
        SnapshotMetadata::new(self.version, self.expires, self.meta)
    }

    /// Construct a new `SignedMetadata<D, SnapshotMetadata>`.
    pub fn signed<D>(
        self,
        private_key: &dyn PrivateKey,
    ) -> Result<SignedMetadata<D, SnapshotMetadata>>
    where
        D: DataInterchange,
    {
        SignedMetadata::new(&self.build()?, private_key)
    }
}

impl Default for SnapshotMetadataBuilder {
    fn default() -> Self {
        SnapshotMetadataBuilder::new()
    }
}

impl From<SnapshotMetadata> for SnapshotMetadataBuilder {
    fn from(meta: SnapshotMetadata) -> Self {
        SnapshotMetadataBuilder {
            version: meta.version,
            expires: meta.expires,
            meta: meta.meta,
        }
    }
}

/// Metadata for the snapshot role.
#[derive(Debug, Clone, PartialEq)]
pub struct SnapshotMetadata {
    version: u32,
    expires: DateTime<Utc>,
    meta: HashMap<MetadataPath, MetadataDescription>,
}

impl SnapshotMetadata {
    /// Create new `SnapshotMetadata`.
    pub fn new(
        version: u32,
        expires: DateTime<Utc>,
        meta: HashMap<MetadataPath, MetadataDescription>,
    ) -> Result<Self> {
        if version < 1 {
            return Err(Error::IllegalArgument(format!(
                "Metadata version must be greater than zero. Found: {}",
                version
            )));
        }

        Ok(SnapshotMetadata {
            version,
            expires,
            meta,
        })
    }

    /// An immutable reference to the metadata paths and descriptions.
    pub fn meta(&self) -> &HashMap<MetadataPath, MetadataDescription> {
        &self.meta
    }
}

impl Metadata for SnapshotMetadata {
    const ROLE: Role = Role::Snapshot;

    fn version(&self) -> u32 {
        self.version
    }

    fn expires(&self) -> &DateTime<Utc> {
        &self.expires
    }
}

impl Serialize for SnapshotMetadata {
    fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        shims::SnapshotMetadata::from(self)
            .map_err(|e| SerializeError::custom(format!("{:?}", e)))?
            .serialize(ser)
    }
}

impl<'de> Deserialize<'de> for SnapshotMetadata {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let intermediate: shims::SnapshotMetadata = Deserialize::deserialize(de)?;
        intermediate
            .try_into()
            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

/// Wrapper for the virtual path to a target.
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord, Serialize)]
pub struct TargetPath(String);

impl TargetPath {
    /// Create a new `TargetPath` from a `String`.
    ///
    /// ```
    /// # use tuf::metadata::TargetPath;
    /// assert!(TargetPath::new("foo").is_ok());
    /// assert!(TargetPath::new("/foo").is_err());
    /// assert!(TargetPath::new("../foo").is_err());
    /// assert!(TargetPath::new("foo/..").is_err());
    /// assert!(TargetPath::new("foo/../bar").is_err());
    /// assert!(TargetPath::new("..foo").is_ok());
    /// assert!(TargetPath::new("foo/..bar").is_ok());
    /// assert!(TargetPath::new("foo/bar..").is_ok());
    /// ```
    pub fn new<P: Into<String>>(path: P) -> Result<Self> {
        let path = path.into();
        safe_path(&path)?;
        Ok(TargetPath(path))
    }

    /// Split `TargetPath` into components that can be joined to create URL paths, Unix
    /// paths, or Windows paths.
    ///
    /// ```
    /// # use tuf::metadata::TargetPath;
    /// let path = TargetPath::new("foo/bar").unwrap();
    /// assert_eq!(path.components(), ["foo".to_string(), "bar".to_string()]);
    /// ```
    pub fn components(&self) -> Vec<String> {
        self.0.split('/').map(|s| s.to_string()).collect()
    }

    /// Return whether this path is the child of another path.
    ///
    /// ```
    /// # use tuf::metadata::TargetPath;
    /// let path1 = TargetPath::new("foo").unwrap();
    /// let path2 = TargetPath::new("foo/bar").unwrap();
    /// assert!(!path2.is_child(&path1));
    ///
    /// let path1 = TargetPath::new("foo/").unwrap();
    /// let path2 = TargetPath::new("foo/bar").unwrap();
    /// assert!(path2.is_child(&path1));
    ///
    /// let path2 = TargetPath::new("foo/bar/baz").unwrap();
    /// assert!(path2.is_child(&path1));
    ///
    /// let path2 = TargetPath::new("wat").unwrap();
    /// assert!(!path2.is_child(&path1))
    /// ```
    pub fn is_child(&self, parent: &Self) -> bool {
        if !parent.0.ends_with('/') {
            return false;
        }

        self.0.starts_with(&parent.0)
    }

    /// Whether or not the current target is available at the end of the given chain of target
    /// paths. For the chain to be valid, each target path in a group must be a child of of all
    /// previous groups.
    // TODO this is hideous and uses way too much clone/heap but I think recursively,
    // so here we are
    pub fn matches_chain(&self, parents: &[HashSet<TargetPath>]) -> bool {
        if parents.is_empty() {
            return false;
        }
        if parents.len() == 1 {
            return parents[0].iter().any(|p| p == self || self.is_child(p));
        }

        let new = parents[1..]
            .iter()
            .map(|group| {
                group
                    .iter()
                    .filter(|parent| {
                        parents[0]
                            .iter()
                            .any(|p| parent.is_child(p) || parent == &p)
                    })
                    .cloned()
                    .collect::<HashSet<_>>()
            })
            .collect::<Vec<_>>();
        self.matches_chain(&*new)
    }

    /// Prefix the target path with a hash value to support TUF spec 5.5.2.
    pub fn with_hash_prefix(&self, hash: &HashValue) -> Result<TargetPath> {
        let mut components = self.components();

        let file_name = components
            .pop()
            .ok_or_else(|| Error::IllegalArgument("Path cannot be empty".into()))?;

        components.push(format!("{}.{}", hash, file_name));

        TargetPath::new(components.join("/"))
    }

    /// The string value of the path.
    pub fn as_str(&self) -> &str {
        &self.0
    }
}

impl ToString for TargetPath {
    fn to_string(&self) -> String {
        self.0.clone()
    }
}

impl<'de> Deserialize<'de> for TargetPath {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let s: String = Deserialize::deserialize(de)?;
        TargetPath::new(s).map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

impl Borrow<str> for TargetPath {
    fn borrow(&self) -> &str {
        self.as_str()
    }
}

/// Description of a target, used in verification.
#[derive(Debug, Clone, PartialEq)]
pub struct TargetDescription {
    length: u64,
    hashes: HashMap<HashAlgorithm, HashValue>,
    custom: HashMap<String, serde_json::Value>,
}

impl TargetDescription {
    /// Create a new `TargetDescription`.
    ///
    /// Note: Creating this manually could lead to errors, and the `from_reader` method is
    /// preferred.
    pub fn new(
        length: u64,
        hashes: HashMap<HashAlgorithm, HashValue>,
        custom: HashMap<String, serde_json::Value>,
    ) -> Result<Self> {
        if hashes.is_empty() {
            return Err(Error::IllegalArgument(
                "Cannot have empty set of hashes".into(),
            ));
        }

        Ok(TargetDescription {
            length,
            hashes,
            custom,
        })
    }

    /// Read the from the given slice and calculate the length and hash values.
    ///
    /// ```
    /// # use data_encoding::BASE64URL;
    /// # use tuf::crypto::{HashAlgorithm,HashValue};
    /// # use tuf::metadata::TargetDescription;
    /// #
    /// let bytes: &[u8] = b"it was a pleasure to burn";
    ///
    /// let target_description = TargetDescription::from_slice(
    ///     bytes,
    ///     &[HashAlgorithm::Sha256, HashAlgorithm::Sha512],
    /// ).unwrap();
    ///
    /// let s = "Rd9zlbzrdWfeL7gnIEi05X-Yv2TCpy4qqZM1N72ZWQs=";
    /// let sha256 = HashValue::new(BASE64URL.decode(s.as_bytes()).unwrap());
    ///
    /// let s ="tuIxwKybYdvJpWuUj6dubvpwhkAozWB6hMJIRzqn2jOUdtDTBg381brV4K\
    ///     BU1zKP8GShoJuXEtCf5NkDTCEJgQ==";
    /// let sha512 = HashValue::new(BASE64URL.decode(s.as_bytes()).unwrap());
    ///
    /// assert_eq!(target_description.length(), bytes.len() as u64);
    /// assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha256), Some(&sha256));
    /// assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha512), Some(&sha512));
    /// ```
    pub fn from_slice(buf: &[u8], hash_algs: &[HashAlgorithm]) -> Result<Self> {
        Self::from_slice_with_custom(buf, hash_algs, HashMap::new())
    }

    /// Read the from the given reader and custom metadata and calculate the length and hash
    /// values.
    ///
    /// ```
    /// # use data_encoding::BASE64URL;
    /// # use serde_json::Value;
    /// # use std::collections::HashMap;
    /// # use tuf::crypto::{HashAlgorithm,HashValue};
    /// # use tuf::metadata::TargetDescription;
    /// #
    /// let bytes: &[u8] = b"it was a pleasure to burn";
    ///
    /// let mut custom = HashMap::new();
    /// custom.insert("Hello".into(), "World".into());
    ///
    /// let target_description = TargetDescription::from_slice_with_custom(
    ///     bytes,
    ///     &[HashAlgorithm::Sha256, HashAlgorithm::Sha512],
    ///     custom,
    /// ).unwrap();
    ///
    /// let s = "Rd9zlbzrdWfeL7gnIEi05X-Yv2TCpy4qqZM1N72ZWQs=";
    /// let sha256 = HashValue::new(BASE64URL.decode(s.as_bytes()).unwrap());
    ///
    /// let s ="tuIxwKybYdvJpWuUj6dubvpwhkAozWB6hMJIRzqn2jOUdtDTBg381brV4K\
    ///     BU1zKP8GShoJuXEtCf5NkDTCEJgQ==";
    /// let sha512 = HashValue::new(BASE64URL.decode(s.as_bytes()).unwrap());
    ///
    /// assert_eq!(target_description.length(), bytes.len() as u64);
    /// assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha256), Some(&sha256));
    /// assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha512), Some(&sha512));
    /// assert_eq!(target_description.custom().get("Hello"), Some(&"World".into()));
    /// ```
    pub fn from_slice_with_custom(
        buf: &[u8],
        hash_algs: &[HashAlgorithm],
        custom: HashMap<String, serde_json::Value>,
    ) -> Result<Self> {
        let hashes = crypto::calculate_hashes_from_slice(buf, hash_algs)?;
        Ok(TargetDescription {
            length: buf.len() as u64,
            hashes,
            custom,
        })
    }

    /// Read the from the given reader and calculate the length and hash values.
    ///
    /// ```
    /// # use data_encoding::BASE64URL;
    /// # use futures_executor::block_on;
    /// # use tuf::crypto::{HashAlgorithm,HashValue};
    /// # use tuf::metadata::TargetDescription;
    /// #
    /// # block_on(async {
    /// let bytes: &[u8] = b"it was a pleasure to burn";
    ///
    /// let target_description = TargetDescription::from_reader(
    ///     bytes,
    ///     &[HashAlgorithm::Sha256, HashAlgorithm::Sha512],
    /// ).await.unwrap();
    ///
    /// let s = "Rd9zlbzrdWfeL7gnIEi05X-Yv2TCpy4qqZM1N72ZWQs=";
    /// let sha256 = HashValue::new(BASE64URL.decode(s.as_bytes()).unwrap());
    ///
    /// let s ="tuIxwKybYdvJpWuUj6dubvpwhkAozWB6hMJIRzqn2jOUdtDTBg381brV4K\
    ///     BU1zKP8GShoJuXEtCf5NkDTCEJgQ==";
    /// let sha512 = HashValue::new(BASE64URL.decode(s.as_bytes()).unwrap());
    ///
    /// assert_eq!(target_description.length(), bytes.len() as u64);
    /// assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha256), Some(&sha256));
    /// assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha512), Some(&sha512));
    /// # })
    /// ```
    pub async fn from_reader<R>(read: R, hash_algs: &[HashAlgorithm]) -> Result<Self>
    where
        R: AsyncRead + Unpin,
    {
        Self::from_reader_with_custom(read, hash_algs, HashMap::new()).await
    }

    /// Read the from the given reader and custom metadata and calculate the length and hash
    /// values.
    ///
    /// ```
    /// # use data_encoding::BASE64URL;
    /// # use futures_executor::block_on;
    /// # use serde_json::Value;
    /// # use std::collections::HashMap;
    /// # use tuf::crypto::{HashAlgorithm,HashValue};
    /// # use tuf::metadata::TargetDescription;
    /// #
    /// # block_on(async {
    /// let bytes: &[u8] = b"it was a pleasure to burn";
    ///
    /// let mut custom = HashMap::new();
    /// custom.insert("Hello".into(), "World".into());
    ///
    /// let target_description = TargetDescription::from_reader_with_custom(
    ///     bytes,
    ///     &[HashAlgorithm::Sha256, HashAlgorithm::Sha512],
    ///     custom,
    /// ).await.unwrap();
    ///
    /// let s = "Rd9zlbzrdWfeL7gnIEi05X-Yv2TCpy4qqZM1N72ZWQs=";
    /// let sha256 = HashValue::new(BASE64URL.decode(s.as_bytes()).unwrap());
    ///
    /// let s ="tuIxwKybYdvJpWuUj6dubvpwhkAozWB6hMJIRzqn2jOUdtDTBg381brV4K\
    ///     BU1zKP8GShoJuXEtCf5NkDTCEJgQ==";
    /// let sha512 = HashValue::new(BASE64URL.decode(s.as_bytes()).unwrap());
    ///
    /// assert_eq!(target_description.length(), bytes.len() as u64);
    /// assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha256), Some(&sha256));
    /// assert_eq!(target_description.hashes().get(&HashAlgorithm::Sha512), Some(&sha512));
    /// assert_eq!(target_description.custom().get("Hello"), Some(&"World".into()));
    /// })
    /// ```
    pub async fn from_reader_with_custom<R>(
        read: R,
        hash_algs: &[HashAlgorithm],
        custom: HashMap<String, serde_json::Value>,
    ) -> Result<Self>
    where
        R: AsyncRead + Unpin,
    {
        let (length, hashes) = crypto::calculate_hashes_from_reader(read, hash_algs).await?;
        Ok(TargetDescription {
            length,
            hashes,
            custom,
        })
    }

    /// The maximum length of the target.
    pub fn length(&self) -> u64 {
        self.length
    }

    /// An immutable reference to the list of calculated hashes.
    pub fn hashes(&self) -> &HashMap<HashAlgorithm, HashValue> {
        &self.hashes
    }

    /// An immutable reference to the custom metadata.
    pub fn custom(&self) -> &HashMap<String, serde_json::Value> {
        &self.custom
    }
}

impl Serialize for TargetDescription {
    fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        shims::TargetDescription::from(self).serialize(ser)
    }
}

impl<'de> Deserialize<'de> for TargetDescription {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let intermediate: shims::TargetDescription = Deserialize::deserialize(de)?;
        intermediate
            .try_into()
            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

/// Metadata for the targets role.
#[derive(Debug, Clone, PartialEq)]
pub struct TargetsMetadata {
    version: u32,
    expires: DateTime<Utc>,
    targets: HashMap<TargetPath, TargetDescription>,
    delegations: Option<Delegations>,
}

impl TargetsMetadata {
    /// Create new `TargetsMetadata`.
    pub fn new(
        version: u32,
        expires: DateTime<Utc>,
        targets: HashMap<TargetPath, TargetDescription>,
        delegations: Option<Delegations>,
    ) -> Result<Self> {
        if version < 1 {
            return Err(Error::IllegalArgument(format!(
                "Metadata version must be greater than zero. Found: {}",
                version
            )));
        }

        Ok(TargetsMetadata {
            version,
            expires,
            targets,
            delegations,
        })
    }

    /// An immutable reference to the descriptions of targets.
    pub fn targets(&self) -> &HashMap<TargetPath, TargetDescription> {
        &self.targets
    }

    /// An immutable reference to the optional delegations.
    pub fn delegations(&self) -> Option<&Delegations> {
        self.delegations.as_ref()
    }
}

impl Metadata for TargetsMetadata {
    const ROLE: Role = Role::Targets;

    fn version(&self) -> u32 {
        self.version
    }

    fn expires(&self) -> &DateTime<Utc> {
        &self.expires
    }
}

impl Serialize for TargetsMetadata {
    fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        shims::TargetsMetadata::from(self)
            .map_err(|e| SerializeError::custom(format!("{:?}", e)))?
            .serialize(ser)
    }
}

impl<'de> Deserialize<'de> for TargetsMetadata {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let intermediate: shims::TargetsMetadata = Deserialize::deserialize(de)?;
        intermediate
            .try_into()
            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

/// Helper to construct `TargetsMetadata`.
pub struct TargetsMetadataBuilder {
    version: u32,
    expires: DateTime<Utc>,
    targets: HashMap<TargetPath, TargetDescription>,
    delegations: Option<Delegations>,
}

impl TargetsMetadataBuilder {
    /// Create a new `TargetsMetadataBuilder`. It defaults to:
    ///
    /// * version: 1
    /// * expires: 90 days from the current time.
    pub fn new() -> Self {
        TargetsMetadataBuilder {
            version: 1,
            expires: Utc::now() + Duration::days(90),
            targets: HashMap::new(),
            delegations: None,
        }
    }

    /// Set the version number for this metadata.
    pub fn version(mut self, version: u32) -> Self {
        self.version = version;
        self
    }

    /// Set the time this metadata expires.
    pub fn expires(mut self, expires: DateTime<Utc>) -> Self {
        self.expires = expires;
        self
    }

    /// Add target to the target metadata.
    pub fn insert_target_from_slice(
        self,
        path: TargetPath,
        buf: &[u8],
        hash_algs: &[HashAlgorithm],
    ) -> Result<Self> {
        let description = TargetDescription::from_slice(buf, hash_algs)?;
        Ok(self.insert_target_description(path, description))
    }

    /// Add target to the target metadata.
    pub async fn insert_target_from_reader<R>(
        self,
        path: TargetPath,
        read: R,
        hash_algs: &[HashAlgorithm],
    ) -> Result<Self>
    where
        R: AsyncRead + Unpin,
    {
        let description = TargetDescription::from_reader(read, hash_algs).await?;
        Ok(self.insert_target_description(path, description))
    }

    /// Add `TargetDescription` to this target metadata target description.
    pub fn insert_target_description(
        mut self,
        path: TargetPath,
        description: TargetDescription,
    ) -> Self {
        self.targets.insert(path, description);
        self
    }

    /// Add `Delegations` to this target metadata.
    pub fn delegations(mut self, delegations: Delegations) -> Self {
        self.delegations = Some(delegations);
        self
    }

    /// Construct a new `TargetsMetadata`.
    pub fn build(self) -> Result<TargetsMetadata> {
        TargetsMetadata::new(self.version, self.expires, self.targets, self.delegations)
    }

    /// Construct a new `SignedMetadata<D, TargetsMetadata>`.
    pub fn signed<D>(
        self,
        private_key: &dyn PrivateKey,
    ) -> Result<SignedMetadata<D, TargetsMetadata>>
    where
        D: DataInterchange,
    {
        SignedMetadata::new(&self.build()?, private_key)
    }
}

impl Default for TargetsMetadataBuilder {
    fn default() -> Self {
        TargetsMetadataBuilder::new()
    }
}

/// Wrapper to described a collections of delegations.
#[derive(Debug, PartialEq, Clone)]
pub struct Delegations {
    keys: HashMap<KeyId, PublicKey>,
    roles: Vec<Delegation>,
}

impl Delegations {
    // TODO check all keys are used
    // TODO check all roles have their ID in the set of keys
    /// Create a new `Delegations` wrapper from the given set of trusted keys and roles.
    pub fn new(keys: HashMap<KeyId, PublicKey>, roles: Vec<Delegation>) -> Result<Self> {
        if keys.is_empty() {
            return Err(Error::IllegalArgument("Keys cannot be empty.".into()));
        }

        if roles.is_empty() {
            return Err(Error::IllegalArgument("Roles cannot be empty.".into()));
        }

        if roles.len()
            != roles
                .iter()
                .map(|r| &r.role)
                .collect::<HashSet<&MetadataPath>>()
                .len()
        {
            return Err(Error::IllegalArgument(
                "Cannot have duplicated roles in delegations.".into(),
            ));
        }

        Ok(Delegations { keys, roles })
    }

    /// An immutable reference to the keys used for this set of delegations.
    pub fn keys(&self) -> &HashMap<KeyId, PublicKey> {
        &self.keys
    }

    /// An immutable reference to the delegated roles.
    pub fn roles(&self) -> &Vec<Delegation> {
        &self.roles
    }
}

impl Serialize for Delegations {
    fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        shims::Delegations::from(self).serialize(ser)
    }
}

impl<'de> Deserialize<'de> for Delegations {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let intermediate: shims::Delegations = Deserialize::deserialize(de)?;
        intermediate
            .try_into()
            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

/// A delegated targets role.
#[derive(Debug, PartialEq, Clone)]
pub struct Delegation {
    role: MetadataPath,
    terminating: bool,
    threshold: u32,
    key_ids: HashSet<KeyId>,
    paths: HashSet<TargetPath>,
}

impl Delegation {
    /// Create a new delegation.
    pub fn new(
        role: MetadataPath,
        terminating: bool,
        threshold: u32,
        key_ids: HashSet<KeyId>,
        paths: HashSet<TargetPath>,
    ) -> Result<Self> {
        if key_ids.is_empty() {
            return Err(Error::IllegalArgument("Cannot have empty key IDs".into()));
        }

        if paths.is_empty() {
            return Err(Error::IllegalArgument("Cannot have empty paths".into()));
        }

        if threshold < 1 {
            return Err(Error::IllegalArgument("Cannot have threshold < 1".into()));
        }

        if (key_ids.len() as u64) < u64::from(threshold) {
            return Err(Error::IllegalArgument(
                "Cannot have threshold less than number of keys".into(),
            ));
        }

        Ok(Delegation {
            role,
            terminating,
            threshold,
            key_ids,
            paths,
        })
    }

    /// An immutable reference to the delegations's metadata path (role).
    pub fn role(&self) -> &MetadataPath {
        &self.role
    }

    /// Whether or not this delegation is terminating.
    pub fn terminating(&self) -> bool {
        self.terminating
    }

    /// An immutable reference to the delegations's trusted key IDs.
    pub fn key_ids(&self) -> &HashSet<KeyId> {
        &self.key_ids
    }

    /// The delegation's threshold.
    pub fn threshold(&self) -> u32 {
        self.threshold
    }

    /// An immutable reference to the delegation's authorized paths.
    pub fn paths(&self) -> &HashSet<TargetPath> {
        &self.paths
    }
}

impl Serialize for Delegation {
    fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        shims::Delegation::from(self).serialize(ser)
    }
}

impl<'de> Deserialize<'de> for Delegation {
    fn deserialize<D: Deserializer<'de>>(de: D) -> ::std::result::Result<Self, D::Error> {
        let intermediate: shims::Delegation = Deserialize::deserialize(de)?;
        intermediate
            .try_into()
            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::crypto::Ed25519PrivateKey;
    use crate::interchange::Json;
    use crate::verify::verify_signatures;
    use assert_matches::assert_matches;
    use chrono::prelude::*;
    use futures_executor::block_on;
    use maplit::{hashmap, hashset};
    use pretty_assertions::assert_eq;
    use serde_json::json;
    use std::str::FromStr;

    const ED25519_1_PK8: &[u8] = include_bytes!("../tests/ed25519/ed25519-1.pk8.der");
    const ED25519_2_PK8: &[u8] = include_bytes!("../tests/ed25519/ed25519-2.pk8.der");
    const ED25519_3_PK8: &[u8] = include_bytes!("../tests/ed25519/ed25519-3.pk8.der");
    const ED25519_4_PK8: &[u8] = include_bytes!("../tests/ed25519/ed25519-4.pk8.der");

    #[test]
    fn no_pardir_in_target_path() {
        let bad_paths = &[
            "..",
            "../some/path",
            "../some/path/",
            "some/../path",
            "some/../path/..",
        ];

        for path in bad_paths.iter() {
            assert!(safe_path(*path).is_err());
            assert!(TargetPath::new(path.to_string()).is_err());
            assert!(MetadataPath::new(path.to_string()).is_err());
            assert!(TargetPath::new(path.to_string()).is_err());
        }
    }

    #[test]
    fn path_matches_chain() {
        let test_cases: &[(bool, &str, &[&[&str]])] = &[
            // simplest case
            (true, "foo", &[&["foo"]]),
            // direct delegation case
            (true, "foo", &[&["foo"], &["foo"]]),
            // is a dir
            (false, "foo", &[&["foo/"]]),
            // target not in last position
            (false, "foo", &[&["foo"], &["bar"]]),
            // target nested
            (true, "foo/bar", &[&["foo/"], &["foo/bar"]]),
            // target illegally nested
            (false, "foo/bar", &[&["baz/"], &["foo/bar"]]),
            // target illegally deeply nested
            (
                false,
                "foo/bar/baz",
                &[&["foo/"], &["foo/quux/"], &["foo/bar/baz"]],
            ),
            // empty
            (false, "foo", &[&[]]),
            // empty 2
            (false, "foo", &[&[], &["foo"]]),
            // empty 3
            (false, "foo", &[&["foo"], &[]]),
        ];

        for case in test_cases {
            let expected = case.0;
            let target = TargetPath::new(case.1).unwrap();
            let parents = case
                .2
                .iter()
                .map(|group| {
                    group
                        .iter()
                        .map(|p| TargetPath::new(p.to_string()).unwrap())
                        .collect::<HashSet<_>>()
                })
                .collect::<Vec<_>>();
            println!(
                "CASE: expect: {} path: {:?} parents: {:?}",
                expected, target, parents
            );
            assert_eq!(target.matches_chain(&parents), expected);
        }
    }

    #[test]
    fn serde_target_path() {
        let s = "foo/bar";
        let t = serde_json::from_str::<TargetPath>(&format!("\"{}\"", s)).unwrap();
        assert_eq!(t.to_string().as_str(), s);
        assert_eq!(serde_json::to_value(t).unwrap(), json!("foo/bar"));
    }

    #[test]
    fn serde_metadata_path() {
        let s = "foo/bar";
        let m = serde_json::from_str::<MetadataPath>(&format!("\"{}\"", s)).unwrap();
        assert_eq!(m.to_string().as_str(), s);
        assert_eq!(serde_json::to_value(m).unwrap(), json!("foo/bar"));
    }

    #[test]
    fn serde_target_description() {
        let s: &[u8] = b"from water does all life begin";
        let description = TargetDescription::from_slice(s, &[HashAlgorithm::Sha256]).unwrap();
        let jsn_str = serde_json::to_string(&description).unwrap();
        let jsn = json!({
            "length": 30,
            "hashes": {
                "sha256": "fc5d745c712bc86ea9a31264dac0c956eeb53857f677eed05829\
                    bb71013cae18",
            },
        });
        let parsed_str: TargetDescription = serde_json::from_str(&jsn_str).unwrap();
        let parsed_jsn: TargetDescription = serde_json::from_value(jsn).unwrap();
        assert_eq!(parsed_str, parsed_jsn);
    }

    #[test]
    fn serde_role_definition() {
        // keyid ordering must be preserved.
        let keyids = vec![
            KeyId::from_str("40e35e8f6003ab90d104710cf88901edab931597401f91c19eeb366060ab3d53")
                .unwrap(),
            KeyId::from_str("01892c662c8cd79fab20edec21de1dcb8b75d9353103face7fe086ff5c0098e4")
                .unwrap(),
            KeyId::from_str("4750eaf6878740780d6f97b12dbad079fb012bec88c78de2c380add56d3f51db")
                .unwrap(),
        ];
        let role_def = RoleDefinition::new(3, keyids).unwrap();
        let jsn = json!({
            "threshold": 3,
            "keyids": [
                "40e35e8f6003ab90d104710cf88901edab931597401f91c19eeb366060ab3d53",
                "01892c662c8cd79fab20edec21de1dcb8b75d9353103face7fe086ff5c0098e4",
                "4750eaf6878740780d6f97b12dbad079fb012bec88c78de2c380add56d3f51db",
            ],
        });
        let encoded = serde_json::to_value(&role_def).unwrap();
        assert_eq!(encoded, jsn);
        let decoded: RoleDefinition = serde_json::from_value(encoded).unwrap();
        assert_eq!(decoded, role_def);
    }

    #[test]
    fn serde_invalid_role_definitions() {
        let jsn = json!({
            "threshold": 0,
            "keyids": [
                "01892c662c8cd79fab20edec21de1dcb8b75d9353103face7fe086ff5c0098e4",
                "4750eaf6878740780d6f97b12dbad079fb012bec88c78de2c380add56d3f51db",
            ],
        });
        assert!(serde_json::from_value::<RoleDefinition>(jsn).is_err());

        let jsn = json!({
            "threshold": -1,
            "keyids": [
                "01892c662c8cd79fab20edec21de1dcb8b75d9353103face7fe086ff5c0098e4",
                "4750eaf6878740780d6f97b12dbad079fb012bec88c78de2c380add56d3f51db",
            ],
        });
        assert!(serde_json::from_value::<RoleDefinition>(jsn).is_err());
    }

    #[test]
    fn serde_root_metadata() {
        let root_key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
        let snapshot_key = Ed25519PrivateKey::from_pkcs8(ED25519_2_PK8).unwrap();
        let targets_key = Ed25519PrivateKey::from_pkcs8(ED25519_3_PK8).unwrap();
        let timestamp_key = Ed25519PrivateKey::from_pkcs8(ED25519_4_PK8).unwrap();

        let root = RootMetadataBuilder::new()
            .expires(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0))
            .root_key(root_key.public().clone())
            .snapshot_key(snapshot_key.public().clone())
            .targets_key(targets_key.public().clone())
            .timestamp_key(timestamp_key.public().clone())
            .build()
            .unwrap();

        let jsn = json!({
            "_type": "root",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "consistent_snapshot": true,
            "keys": {
                "09557ed63f91b5b95917d46f66c63ea79bdaef1b008ba823808bca849f1d18a1": {
                    "keytype": "ed25519",
                    "scheme": "ed25519",
                    "keyid_hash_algorithms": ["sha256", "sha512"],
                    "keyval": {
                        "public": "1410ae3053aa70bbfa98428a879d64d3002a3578f7dfaaeb1cb0764e860f7e0b",
                    },
                },
                "40e35e8f6003ab90d104710cf88901edab931597401f91c19eeb366060ab3d53": {
                    "keytype": "ed25519",
                    "scheme": "ed25519",
                    "keyid_hash_algorithms": ["sha256", "sha512"],
                    "keyval": {
                        "public": "166376c90a7f717d027056272f361c252fb050bed1a067ff2089a0302fbab73d",
                    },
                },
                "a9f3ebc9b138762563a9c27b6edd439959e559709babd123e8d449ba2c18c61a": {
                    "keytype": "ed25519",
                    "scheme": "ed25519",
                    "keyid_hash_algorithms": ["sha256", "sha512"],
                    "keyval": {
                        "public": "eb8ac26b5c9ef0279e3be3e82262a93bce16fe58ee422500d38caf461c65a3b6",
                    },
                },
                "fd7b7741686fa44903f1e4b61d7db869939f402b4acedc044767922c7d309983": {
                    "keytype": "ed25519",
                    "scheme": "ed25519",
                    "keyid_hash_algorithms": ["sha256", "sha512"],
                    "keyval": {
                        "public": "68d9ecb387371005a8eb8e60105305c34356a8fcd859d7fef3cc228bf2b2b3b2",
                    },
                }
            },
            "roles": {
                "root": {
                    "threshold": 1,
                    "keyids": ["a9f3ebc9b138762563a9c27b6edd439959e559709babd123e8d449ba2c18c61a"],
                },
                "snapshot": {
                    "threshold": 1,
                    "keyids": ["fd7b7741686fa44903f1e4b61d7db869939f402b4acedc044767922c7d309983"],
                },
                "targets": {
                    "threshold": 1,
                    "keyids": ["40e35e8f6003ab90d104710cf88901edab931597401f91c19eeb366060ab3d53"],
                },
                "timestamp": {
                    "threshold": 1,
                    "keyids": ["09557ed63f91b5b95917d46f66c63ea79bdaef1b008ba823808bca849f1d18a1"],
                },
            },
        });

        let encoded = serde_json::to_value(&root).unwrap();
        assert_eq!(encoded, jsn);
        let decoded: RootMetadata = serde_json::from_value(encoded).unwrap();
        assert_eq!(decoded, root);
    }

    fn jsn_root_metadata_without_keyid_hash_algos() -> serde_json::Value {
        json!({
            "_type": "root",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "consistent_snapshot": false,
            "keys": {
                "12435b260b6172bd750aeb102f54a347c56b109e0524ab1f144593c07af66356": {
                    "keytype": "ed25519",
                    "scheme": "ed25519",
                    "keyval": {
                        "public": "68d9ecb387371005a8eb8e60105305c34356a8fcd859d7fef3cc228bf2b2b3b2",
                    },
                },
                "3af6b427c05274532231760f39d81212fdf8ac1a9f8fddf12722623ccec02fec": {
                    "keytype": "ed25519",
                    "scheme": "ed25519",
                    "keyval": {
                        "public": "1410ae3053aa70bbfa98428a879d64d3002a3578f7dfaaeb1cb0764e860f7e0b",
                    },
                },
                "b9c336828063cf4fe5348e9fe2d86827c7b3104a76b1f4484a56bbef1ef08cfb": {
                    "keytype": "ed25519",
                    "scheme": "ed25519",
                    "keyval": {
                        "public": "166376c90a7f717d027056272f361c252fb050bed1a067ff2089a0302fbab73d",
                    },
                },
                "e0294a3f17cc8563c3ed5fceb3bd8d3f6bfeeaca499b5c9572729ae015566554": {
                    "keytype": "ed25519",
                    "scheme": "ed25519",
                    "keyval": {
                        "public": "eb8ac26b5c9ef0279e3be3e82262a93bce16fe58ee422500d38caf461c65a3b6",
                    },
                }
            },
            "roles": {
                "root": {
                    "threshold": 1,
                    "keyids": ["e0294a3f17cc8563c3ed5fceb3bd8d3f6bfeeaca499b5c9572729ae015566554"],
                },
                "snapshot": {
                    "threshold": 1,
                    "keyids": ["12435b260b6172bd750aeb102f54a347c56b109e0524ab1f144593c07af66356"],
                },
                "targets": {
                    "threshold": 1,
                    "keyids": ["b9c336828063cf4fe5348e9fe2d86827c7b3104a76b1f4484a56bbef1ef08cfb"],
                },
                "timestamp": {
                    "threshold": 1,
                    "keyids": ["3af6b427c05274532231760f39d81212fdf8ac1a9f8fddf12722623ccec02fec"],
                },
            },
        })
    }

    #[test]
    fn de_ser_root_metadata_without_keyid_hash_algorithms() {
        let jsn = jsn_root_metadata_without_keyid_hash_algos();
        let decoded: RootMetadata = serde_json::from_value(jsn.clone()).unwrap();
        let encoded = serde_json::to_value(decoded).unwrap();

        assert_eq!(jsn, encoded);
    }

    #[test]
    fn de_ser_root_metadata_wrong_key_id() {
        let jsn = jsn_root_metadata_without_keyid_hash_algos();
        let mut jsn_str = str::from_utf8(&Json::canonicalize(&jsn).unwrap())
            .unwrap()
            .to_owned();
        // Replace the key id to something else.
        jsn_str = jsn_str.replace(
            "12435b260b6172bd750aeb102f54a347c56b109e0524ab1f144593c07af66356",
            "00435b260b6172bd750aeb102f54a347c56b109e0524ab1f144593c07af66356",
        );
        let decoded: RootMetadata = serde_json::from_str(&jsn_str).unwrap();
        assert_eq!(3, decoded.keys.len());
    }

    #[test]
    fn sign_and_verify_root_metadata() {
        let jsn = jsn_root_metadata_without_keyid_hash_algos();
        let root_key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
        let decoded: RootMetadata = serde_json::from_value(jsn).unwrap();

        let signed: SignedMetadata<crate::interchange::cjson::Json, _> =
            SignedMetadata::new(&decoded, &root_key).unwrap();
        let raw_root = signed.to_raw().unwrap();

        assert_matches!(
            verify_signatures(&raw_root, 1, &[root_key.public().clone()]),
            Ok(_)
        );
    }

    #[test]
    fn verify_signed_serialized_root_metadata() {
        let jsn = json!({
            "signatures": [{
                "keyid": "a9f3ebc9b138762563a9c27b6edd439959e559709babd123e8d449ba2c18c61a",
                "sig": "c4ba838e0d3f783716393a4d691f568f840733ff488bb79ac68287e97e0b31d63fcef392dbc978e878c2103ba231905af634cc651d6f0e63a35782d051ac6e00"
            }],
            "signed": jsn_root_metadata_without_keyid_hash_algos()
        });
        let root_key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
        let decoded: SignedMetadata<crate::interchange::cjson::Json, RootMetadata> =
            serde_json::from_value(jsn).unwrap();
        let raw_root = decoded.to_raw().unwrap();

        assert_matches!(
            verify_signatures(&raw_root, 1, &[root_key.public().clone()]),
            Ok(_)
        );
    }

    #[test]
    fn verify_signed_serialized_root_metadata_with_duplicate_sig() {
        let jsn = json!({
            "signatures": [{
                "keyid": "a9f3ebc9b138762563a9c27b6edd439959e559709babd123e8d449ba2c18c61a",
                "sig": "c4ba838e0d3f783716393a4d691f568f840733ff488bb79ac68287e97e0b31d63fcef392dbc978e878c2103ba231905af634cc651d6f0e63a35782d051ac6e00"
            },
            {
                "keyid": "a9f3ebc9b138762563a9c27b6edd439959e559709babd123e8d449ba2c18c61a",
                "sig": "c4ba838e0d3f783716393a4d691f568f840733ff488bb79ac68287e97e0b31d63fcef392dbc978e878c2103ba231905af634cc651d6f0e63a35782d051ac6e00"
            }],
            "signed": jsn_root_metadata_without_keyid_hash_algos()
        });
        let root_key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
        let decoded: SignedMetadata<crate::interchange::cjson::Json, RootMetadata> =
            serde_json::from_value(jsn).unwrap();
        let raw_root = decoded.to_raw().unwrap();
        assert_matches!(
            verify_signatures(&raw_root, 2, &[root_key.public().clone()]),
            Err(Error::VerificationFailure(_))
        );
        assert_matches!(
            verify_signatures(&raw_root, 1, &[root_key.public().clone()]),
            Ok(_)
        );
    }

    fn verify_signature_with_unknown_fields<M>(mut metadata: serde_json::Value)
    where
        M: Metadata,
    {
        let key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
        let public_keys = vec![key.public().clone()];

        let mut standard = SignedMetadataBuilder::<Json, M>::from_raw_metadata(metadata.clone())
            .unwrap()
            .sign(&key)
            .unwrap()
            .build()
            .to_raw()
            .unwrap()
            .parse_untrusted()
            .unwrap();

        metadata.as_object_mut().unwrap().insert(
            "custom".into(),
            json!({
                "metadata": ["please", "sign", "me"],
                "this-too": 42,
            }),
        );
        let mut custom = SignedMetadataBuilder::<Json, M>::from_raw_metadata(metadata)
            .unwrap()
            .sign(&key)
            .unwrap()
            .build()
            .to_raw()
            .unwrap()
            .parse_untrusted()
            .unwrap();

        // Ensure the signatures are valid as-is.
        assert_matches!(
            verify_signatures(&standard.to_raw().unwrap(), 1, &public_keys),
            Ok(_)
        );
        assert_matches!(
            verify_signatures(&custom.to_raw().unwrap(), 1, std::iter::once(key.public())),
            Ok(_)
        );

        // But not if the metadata was signed with custom fields and they are now missing or
        // unexpected new fields appear.
        std::mem::swap(&mut standard.metadata, &mut custom.metadata);
        assert_matches!(
            verify_signatures(
                &standard.to_raw().unwrap(),
                1,
                std::iter::once(key.public())
            ),
            Err(Error::VerificationFailure(_))
        );
        assert_matches!(
            verify_signatures(&custom.to_raw().unwrap(), 1, std::iter::once(key.public())),
            Err(Error::VerificationFailure(_))
        );
    }

    #[test]
    fn unknown_fields_included_in_root_metadata_signature() {
        verify_signature_with_unknown_fields::<RootMetadata>(
            jsn_root_metadata_without_keyid_hash_algos(),
        );
    }

    #[test]
    fn unknown_fields_included_in_timestamp_metadata_signature() {
        verify_signature_with_unknown_fields::<TimestampMetadata>(make_timestamp());
    }

    #[test]
    fn unknown_fields_included_in_snapshot_metadata_signature() {
        verify_signature_with_unknown_fields::<SnapshotMetadata>(make_snapshot());
    }

    #[test]
    fn unknown_fields_included_in_targets_metadata_signature() {
        verify_signature_with_unknown_fields::<TargetsMetadata>(make_targets());
    }

    #[test]
    fn serde_timestamp_metadata() {
        let description = MetadataDescription::new(
            1,
            Some(100),
            hashmap! { HashAlgorithm::Sha256 => HashValue::new(vec![]) },
        )
        .unwrap();

        let timestamp = TimestampMetadataBuilder::from_metadata_description(description)
            .expires(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0))
            .build()
            .unwrap();

        let jsn = json!({
            "_type": "timestamp",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "meta": {
                "snapshot.json": {
                    "version": 1,
                    "length": 100,
                    "hashes": {
                        "sha256": "",
                    },
                },
            }
        });

        let encoded = serde_json::to_value(&timestamp).unwrap();
        assert_eq!(encoded, jsn);
        let decoded: TimestampMetadata = serde_json::from_value(encoded).unwrap();
        assert_eq!(decoded, timestamp);
    }

    // Deserialize timestamp metadata with optional length and hashes
    #[test]
    fn serde_timestamp_metadata_without_length_and_hashes() {
        let description = MetadataDescription::new(1, None, HashMap::new()).unwrap();

        let timestamp = TimestampMetadataBuilder::from_metadata_description(description)
            .expires(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0))
            .build()
            .unwrap();

        let jsn = json!({
            "_type": "timestamp",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "meta": {
                "snapshot.json": {
                    "version": 1
                },
            }
        });

        let encoded = serde_json::to_value(&timestamp).unwrap();
        assert_eq!(encoded, jsn);
        let decoded: TimestampMetadata = serde_json::from_value(encoded).unwrap();
        assert_eq!(decoded, timestamp);
    }

    #[test]
    fn serde_timestamp_metadata_missing_snapshot() {
        let jsn = json!({
            "_type": "timestamp",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "meta": {}
        });

        assert_matches!(
            serde_json::from_value::<TimestampMetadata>(jsn),
            Err(ref err) if err.to_string() == "missing field `snapshot.json`"
        );
    }

    #[test]
    fn serde_timestamp_metadata_extra_metadata() {
        let jsn = json!({
            "_type": "timestamp",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "meta": {
                "snapshot.json": {
                    "version": 1,
                    "length": 100,
                    "hashes": {
                        "sha256": "",
                    },
                },
                "targets.json": {
                    "version": 1,
                    "length": 100,
                    "hashes": {
                        "sha256": "",
                    },
                },
            }
        });

        assert_matches!(
            serde_json::from_value::<TimestampMetadata>(jsn),
            Err(ref err) if err.to_string() ==
            "unknown field `targets.json`, expected `snapshot.json`"
        );
    }

    #[test]
    fn serde_snapshot_metadata() {
        let snapshot = SnapshotMetadataBuilder::new()
            .expires(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0))
            .insert_metadata_description(
                MetadataPath::new("targets").unwrap(),
                MetadataDescription::new(
                    1,
                    Some(100),
                    hashmap! { HashAlgorithm::Sha256 => HashValue::new(vec![]) },
                )
                .unwrap(),
            )
            .build()
            .unwrap();

        let jsn = json!({
            "_type": "snapshot",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "meta": {
                "targets.json": {
                    "version": 1,
                    "length": 100,
                    "hashes": {
                        "sha256": "",
                    },
                },
            },
        });

        let encoded = serde_json::to_value(&snapshot).unwrap();
        assert_eq!(encoded, jsn);
        let decoded: SnapshotMetadata = serde_json::from_value(encoded).unwrap();
        assert_eq!(decoded, snapshot);
    }

    // Deserialize snapshot metadata with optional length and hashes
    #[test]
    fn serde_snapshot_optional_length_and_hashes() {
        let snapshot = SnapshotMetadataBuilder::new()
            .expires(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0))
            .insert_metadata_description(
                MetadataPath::new("targets").unwrap(),
                MetadataDescription::new(1, None, HashMap::new()).unwrap(),
            )
            .build()
            .unwrap();

        let jsn = json!({
            "_type": "snapshot",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "meta": {
                "targets.json": {
                    "version": 1,
                },
            },
        });

        let encoded = serde_json::to_value(&snapshot).unwrap();
        assert_eq!(encoded, jsn);
        let decoded: SnapshotMetadata = serde_json::from_value(encoded).unwrap();
        assert_eq!(decoded, snapshot);
    }

    #[test]
    fn serde_targets_metadata() {
        block_on(async {
            let targets = TargetsMetadataBuilder::new()
                .expires(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0))
                .insert_target_from_slice(
                    TargetPath::new("insert-target-from-slice").unwrap(),
                    &b"foo"[..],
                    &[HashAlgorithm::Sha256],
                )
                .unwrap()
                .insert_target_from_reader(
                    TargetPath::new("insert-target-from-reader").unwrap(),
                    &b"foo"[..],
                    &[HashAlgorithm::Sha256],
                )
                .await
                .unwrap()
                .insert_target_description(
                    TargetPath::new("insert-target-description-from-slice-with-custom").unwrap(),
                    TargetDescription::from_slice_with_custom(
                        &b"foo"[..],
                        &[HashAlgorithm::Sha256],
                        HashMap::new(),
                    )
                    .unwrap(),
                )
                .insert_target_description(
                    TargetPath::new("insert-target-description-from-reader-with-custom").unwrap(),
                    TargetDescription::from_reader_with_custom(
                        &b"foo"[..],
                        &[HashAlgorithm::Sha256],
                        hashmap! {
                            "foo".into() => 1.into(),
                            "bar".into() => "baz".into(),
                        },
                    )
                    .await
                    .unwrap(),
                )
                .build()
                .unwrap();

            let jsn = json!({
                "_type": "targets",
                "spec_version": "1.0",
                "version": 1,
                "expires": "2017-01-01T00:00:00Z",
                "targets": {
                    "insert-target-from-slice": {
                        "length": 3,
                        "hashes": {
                            "sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483\
                                bfa0f98a5e886266e7ae",
                        },
                    },
                    "insert-target-description-from-slice-with-custom": {
                        "length": 3,
                        "hashes": {
                            "sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483\
                                bfa0f98a5e886266e7ae",
                        },
                    },
                    "insert-target-from-reader": {
                        "length": 3,
                        "hashes": {
                            "sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483\
                                bfa0f98a5e886266e7ae",
                        },
                    },
                    "insert-target-description-from-reader-with-custom": {
                        "length": 3,
                        "hashes": {
                            "sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483\
                                bfa0f98a5e886266e7ae",
                        },
                        "custom": {
                            "foo": 1,
                            "bar": "baz",
                        },
                    },
                },
            });

            let encoded = serde_json::to_value(&targets).unwrap();
            assert_eq!(encoded, jsn);
            let decoded: TargetsMetadata = serde_json::from_value(encoded).unwrap();
            assert_eq!(decoded, targets);
        })
    }

    #[test]
    fn serde_targets_with_delegations_metadata() {
        let key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
        let delegations = Delegations::new(
            hashmap! { key.public().key_id().clone() => key.public().clone() },
            vec![Delegation::new(
                MetadataPath::new("foo/bar").unwrap(),
                false,
                1,
                hashset!(key.public().key_id().clone()),
                hashset!(TargetPath::new("baz/quux").unwrap()),
            )
            .unwrap()],
        )
        .unwrap();

        let targets = TargetsMetadataBuilder::new()
            .expires(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0))
            .delegations(delegations)
            .build()
            .unwrap();

        let jsn = json!({
            "_type": "targets",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "targets": {},
            "delegations": {
                "keys": {
                    "a9f3ebc9b138762563a9c27b6edd439959e559709babd123e8d449ba2c18c61a": {
                        "keytype": "ed25519",
                        "scheme": "ed25519",
                        "keyid_hash_algorithms": ["sha256", "sha512"],
                        "keyval": {
                            "public": "eb8ac26b5c9ef0279e3be3e82262a93bce16fe58\
                                ee422500d38caf461c65a3b6",
                        }
                    },
                },
                "roles": [
                    {
                        "role": "foo/bar",
                        "terminating": false,
                        "threshold": 1,
                        "keyids": ["a9f3ebc9b138762563a9c27b6edd439959e559709babd123e8d449ba2c18c61a"],
                        "paths": ["baz/quux"],
                    },
                ],
            }
        });

        let encoded = serde_json::to_value(&targets).unwrap();
        assert_eq!(encoded, jsn);
        let decoded: TargetsMetadata = serde_json::from_value(encoded).unwrap();
        assert_eq!(decoded, targets);
    }

    #[test]
    fn serde_signed_metadata() {
        let snapshot = SnapshotMetadataBuilder::new()
            .expires(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0))
            .insert_metadata_description(
                MetadataPath::new("targets").unwrap(),
                MetadataDescription::new(
                    1,
                    Some(100),
                    hashmap! { HashAlgorithm::Sha256 => HashValue::new(vec![]) },
                )
                .unwrap(),
            )
            .build()
            .unwrap();

        let key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();

        let signed = SignedMetadata::<Json, _>::new(&snapshot, &key).unwrap();

        let jsn = json!({
            "signatures": [
                {
                    "keyid": "a9f3ebc9b138762563a9c27b6edd439959e559709babd123e8d449ba2c18c61a",
                    "sig": "ea48ddc7b3ea614b394e508eb8722100f94ff1a4e3aac3af09d\
                        a0dada4f878431e8ac26160833405ec239924dfe62edf605fee8294\
                        c49b4acade55c76e817602",
                }
            ],
            "signed": {
                "_type": "snapshot",
                "spec_version": "1.0",
                "version": 1,
                "expires": "2017-01-01T00:00:00Z",
                "meta": {
                    "targets.json": {
                        "version": 1,
                        "length": 100,
                        "hashes": {
                            "sha256": "",
                        },
                    },
                },
            },
        });

        let encoded = serde_json::to_value(&signed).unwrap();
        assert_eq!(encoded, jsn, "{:#?} != {:#?}", encoded, jsn);
        let decoded: SignedMetadata<Json, SnapshotMetadata> =
            serde_json::from_value(encoded).unwrap();
        assert_eq!(decoded, signed);
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Here there be test cases about what metadata is allowed to be parsed wherein we do all sorts
    // of naughty things and make sure the parsers puke appropriately.
    //                                   ______________
    //                             ,===:'.,            `-._
    //                                  `:.`---.__         `-._
    //                                    `:.     `--.         `.
    //                                      \.        `.         `.
    //                              (,,(,    \.         `.   ____,-`.,
    //                           (,'     `/   \.   ,--.___`.'
    //                       ,  ,'  ,--.  `,   \.;'         `
    //                        `{o, {    \  :    \;
    //                          |,,'    /  /    //
    //                          j;;    /  ,' ,-//.    ,---.      ,
    //                          \;'   /  ,' /  _  \  /  _  \   ,'/
    //                                \   `'  / \  `'  / \  `.' /
    //                                 `.___,'   `.__,'   `.__,'
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////

    // TODO test for mismatched ed25519/rsa keys/schemes

    fn make_root() -> serde_json::Value {
        let root_key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8).unwrap();
        let snapshot_key = Ed25519PrivateKey::from_pkcs8(ED25519_2_PK8).unwrap();
        let targets_key = Ed25519PrivateKey::from_pkcs8(ED25519_3_PK8).unwrap();
        let timestamp_key = Ed25519PrivateKey::from_pkcs8(ED25519_4_PK8).unwrap();

        let root = RootMetadataBuilder::new()
            .expires(Utc.ymd(2038, 1, 1).and_hms(0, 0, 0))
            .root_key(root_key.public().clone())
            .snapshot_key(snapshot_key.public().clone())
            .targets_key(targets_key.public().clone())
            .timestamp_key(timestamp_key.public().clone())
            .build()
            .unwrap();

        serde_json::to_value(&root).unwrap()
    }

    fn make_snapshot() -> serde_json::Value {
        let snapshot = SnapshotMetadataBuilder::new()
            .expires(Utc.ymd(2038, 1, 1).and_hms(0, 0, 0))
            .build()
            .unwrap();

        serde_json::to_value(&snapshot).unwrap()
    }

    fn make_timestamp() -> serde_json::Value {
        let description =
            MetadataDescription::from_slice(&[][..], 1, &[HashAlgorithm::Sha256]).unwrap();

        let timestamp = TimestampMetadataBuilder::from_metadata_description(description)
            .expires(Utc.ymd(2017, 1, 1).and_hms(0, 0, 0))
            .build()
            .unwrap();

        serde_json::to_value(&timestamp).unwrap()
    }

    fn make_targets() -> serde_json::Value {
        let targets =
            TargetsMetadata::new(1, Utc.ymd(2038, 1, 1).and_hms(0, 0, 0), hashmap!(), None)
                .unwrap();

        serde_json::to_value(&targets).unwrap()
    }

    fn make_delegations() -> serde_json::Value {
        let key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8)
            .unwrap()
            .public()
            .clone();
        let delegations = Delegations::new(
            hashmap! { key.key_id().clone() => key.clone() },
            vec![Delegation::new(
                MetadataPath::new("foo").unwrap(),
                false,
                1,
                hashset!(key.key_id().clone()),
                hashset!(TargetPath::new("bar").unwrap()),
            )
            .unwrap()],
        )
        .unwrap();

        serde_json::to_value(&delegations).unwrap()
    }

    fn make_delegation() -> serde_json::Value {
        let key = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8)
            .unwrap()
            .public()
            .clone();
        let delegation = Delegation::new(
            MetadataPath::new("foo").unwrap(),
            false,
            1,
            hashset!(key.key_id().clone()),
            hashset!(TargetPath::new("bar").unwrap()),
        )
        .unwrap();

        serde_json::to_value(&delegation).unwrap()
    }

    fn set_version(value: &mut serde_json::Value, version: i64) {
        match value.as_object_mut() {
            Some(obj) => {
                let _ = obj.insert("version".into(), json!(version));
            }
            None => panic!(),
        }
    }

    // Refuse to deserialize root metadata if the version is not > 0
    #[test]
    fn deserialize_json_root_illegal_version() {
        let mut root_json = make_root();
        set_version(&mut root_json, 0);
        assert!(serde_json::from_value::<RootMetadata>(root_json.clone()).is_err());

        let mut root_json = make_root();
        set_version(&mut root_json, -1);
        assert!(serde_json::from_value::<RootMetadata>(root_json).is_err());
    }

    // Refuse to deserialize root metadata if it contains duplicate keys
    #[test]
    fn deserialize_json_root_duplicate_keys() {
        let root_json = r#"{
            "_type": "root",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "consistent_snapshot": false,
            "keys": {
                "09557ed63f91b5b95917d46f66c63ea79bdaef1b008ba823808bca849f1d18a1": {
                    "keytype": "ed25519",
                    "scheme": "ed25519",
                    "keyval": {
                        "public": "1410ae3053aa70bbfa98428a879d64d3002a3578f7dfaaeb1cb0764e860f7e0b"
                    }
                },
                "09557ed63f91b5b95917d46f66c63ea79bdaef1b008ba823808bca849f1d18a1": {
                    "keytype": "ed25519",
                    "scheme": "ed25519",
                    "keyval": {
                        "public": "166376c90a7f717d027056272f361c252fb050bed1a067ff2089a0302fbab73d"
                    }
                }
            },
            "roles": {
                "root": {
                    "threshold": 1,
                    "keyids": ["09557ed63f91b5b95917d46f66c63ea79bdaef1b008ba823808bca849f1d18a1"]
                },
                "snapshot": {
                    "threshold": 1,
                    "keyids": ["09557ed63f91b5b95917d46f66c63ea79bdaef1b008ba823808bca849f1d18a1"]
                },
                "targets": {
                    "threshold": 1,
                    "keyids": ["09557ed63f91b5b95917d46f66c63ea79bdaef1b008ba823808bca849f1d18a1"]
                },
                "timestamp": {
                    "threshold": 1,
                    "keyids": ["09557ed63f91b5b95917d46f66c63ea79bdaef1b008ba823808bca849f1d18a1"]
                }
            }
        }"#;
        match serde_json::from_str::<RootMetadata>(root_json) {
            Err(ref err) if err.is_data() => {
                assert!(
                    err.to_string().starts_with("Cannot have duplicate keys"),
                    "unexpected err: {:?}",
                    err
                );
            }
            result => panic!("unexpected result: {:?}", result),
        }
    }

    fn set_threshold(value: &mut serde_json::Value, threshold: i32) {
        match value.as_object_mut() {
            Some(obj) => {
                let _ = obj.insert("threshold".into(), json!(threshold));
            }
            None => panic!(),
        }
    }

    // Refuse to deserialize role definitions with illegal thresholds
    #[test]
    fn deserialize_json_role_definition_illegal_threshold() {
        let role_def = RoleDefinition::new(
            1,
            vec![Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8)
                .unwrap()
                .public()
                .key_id()
                .clone()],
        )
        .unwrap();

        let mut jsn = serde_json::to_value(&role_def).unwrap();
        set_threshold(&mut jsn, 0);
        assert!(serde_json::from_value::<RoleDefinition>(jsn).is_err());

        let mut jsn = serde_json::to_value(&role_def).unwrap();
        set_threshold(&mut jsn, -1);
        assert!(serde_json::from_value::<RoleDefinition>(jsn).is_err());

        let role_def = RoleDefinition::new(
            2,
            vec![
                Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8)
                    .unwrap()
                    .public()
                    .key_id()
                    .clone(),
                Ed25519PrivateKey::from_pkcs8(ED25519_2_PK8)
                    .unwrap()
                    .public()
                    .key_id()
                    .clone(),
            ],
        )
        .unwrap();

        let mut jsn = serde_json::to_value(&role_def).unwrap();
        set_threshold(&mut jsn, 3);
        assert!(serde_json::from_value::<RoleDefinition>(jsn).is_err());
    }

    // Refuse to deserialize root metadata with wrong type field
    #[test]
    fn deserialize_json_root_bad_type() {
        let mut root = make_root();
        let _ = root
            .as_object_mut()
            .unwrap()
            .insert("_type".into(), json!("snapshot"));
        assert!(serde_json::from_value::<RootMetadata>(root).is_err());
    }

    // Refuse to deserialize root metadata with unknown spec version
    #[test]
    fn deserialize_json_root_bad_spec_version() {
        let mut root = make_root();
        let _ = root
            .as_object_mut()
            .unwrap()
            .insert("spec_version".into(), json!("0"));
        assert!(serde_json::from_value::<RootMetadata>(root).is_err());
    }

    // Refuse to deserialize role definitions with duplicated key ids
    #[test]
    fn deserialize_json_role_definition_duplicate_key_ids() {
        let key_id = Ed25519PrivateKey::from_pkcs8(ED25519_1_PK8)
            .unwrap()
            .public()
            .key_id()
            .clone();
        let role_def = RoleDefinition::new(1, vec![key_id.clone()]).unwrap();
        let mut jsn = serde_json::to_value(&role_def).unwrap();

        match jsn.as_object_mut() {
            Some(obj) => match obj.get_mut("keyids").unwrap().as_array_mut() {
                Some(arr) => arr.push(json!(key_id)),
                None => panic!(),
            },
            None => panic!(),
        }

        assert!(serde_json::from_value::<RoleDefinition>(jsn).is_err());
    }

    // Refuse to deserialize snapshot metadata with illegal versions
    #[test]
    fn deserialize_json_snapshot_illegal_version() {
        let mut snapshot = make_snapshot();
        set_version(&mut snapshot, 0);
        assert!(serde_json::from_value::<SnapshotMetadata>(snapshot).is_err());

        let mut snapshot = make_snapshot();
        set_version(&mut snapshot, -1);
        assert!(serde_json::from_value::<SnapshotMetadata>(snapshot).is_err());
    }

    // Refuse to deserialize snapshot metadata with wrong type field
    #[test]
    fn deserialize_json_snapshot_bad_type() {
        let mut snapshot = make_snapshot();
        let _ = snapshot
            .as_object_mut()
            .unwrap()
            .insert("_type".into(), json!("root"));
        assert!(serde_json::from_value::<SnapshotMetadata>(snapshot).is_err());
    }

    // Refuse to deserialize snapshot metadata with unknown spec version
    #[test]
    fn deserialize_json_snapshot_spec_version() {
        let mut snapshot = make_snapshot();
        let _ = snapshot
            .as_object_mut()
            .unwrap()
            .insert("spec_version".into(), json!("0"));
        assert!(serde_json::from_value::<SnapshotMetadata>(snapshot).is_err());
    }

    // Refuse to deserialize snapshot metadata if it contains duplicate metadata
    #[test]
    fn deserialize_json_snapshot_duplicate_metadata() {
        let snapshot_json = r#"{
            "_type": "snapshot",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "meta": {
                "targets.json": {
                    "version": 1,
                    "length": 100,
                    "hashes": {
                        "sha256": ""
                    }
                },
                "targets.json": {
                    "version": 1,
                    "length": 100,
                    "hashes": {
                        "sha256": ""
                    }
                }
            }
        }"#;
        match serde_json::from_str::<SnapshotMetadata>(snapshot_json) {
            Err(ref err) if err.is_data() => {}
            result => panic!("unexpected result: {:?}", result),
        }
    }

    // Refuse to deserialize timestamp metadata with illegal versions
    #[test]
    fn deserialize_json_timestamp_illegal_version() {
        let mut timestamp = make_timestamp();
        set_version(&mut timestamp, 0);
        assert!(serde_json::from_value::<TimestampMetadata>(timestamp).is_err());

        let mut timestamp = make_timestamp();
        set_version(&mut timestamp, -1);
        assert!(serde_json::from_value::<TimestampMetadata>(timestamp).is_err());
    }

    // Refuse to deserialize timestamp metadata with wrong type field
    #[test]
    fn deserialize_json_timestamp_bad_type() {
        let mut timestamp = make_timestamp();
        let _ = timestamp
            .as_object_mut()
            .unwrap()
            .insert("_type".into(), json!("root"));
        assert!(serde_json::from_value::<TimestampMetadata>(timestamp).is_err());
    }

    // Refuse to deserialize timestamp metadata with unknown spec version
    #[test]
    fn deserialize_json_timestamp_bad_spec_version() {
        let mut timestamp = make_timestamp();
        let _ = timestamp
            .as_object_mut()
            .unwrap()
            .insert("spec_version".into(), json!("0"));
        assert!(serde_json::from_value::<TimestampMetadata>(timestamp).is_err());
    }

    // Refuse to deserialize timestamp metadata if it contains duplicate metadata
    #[test]
    fn deserialize_json_timestamp_duplicate_metadata() {
        let timestamp_json = r#"{
            "_type": "timestamp",
            "spec_version": "1.0",
            "version": 1,
            "expires": "2017-01-01T00:00:00Z",
            "meta": {
                "snapshot.json": {
                    "version": 1,
                    "length": 100,
                    "hashes": {
                        "sha256": ""
                    }
                },
                "snapshot.json": {
                    "version": 1,
                    "length": 100,
                    "hashes": {
                        "sha256": ""
                    }
                }
            }
        }"#;
        match serde_json::from_str::<TimestampMetadata>(timestamp_json) {
            Err(ref err) if err.is_data() => {}
            result => panic!("unexpected result: {:?}", result),
        }
    }

    // Refuse to deserialize targets metadata with illegal versions
    #[test]
    fn deserialize_json_targets_illegal_version() {
        let mut targets = make_targets();
        set_version(&mut targets, 0);
        assert!(serde_json::from_value::<TargetsMetadata>(targets).is_err());

        let mut targets = make_targets();
        set_version(&mut targets, -1);
        assert!(serde_json::from_value::<TargetsMetadata>(targets).is_err());
    }

    // Refuse to deserialize targets metadata with wrong type field
    #[test]
    fn deserialize_json_targets_bad_type() {
        let mut targets = make_targets();
        let _ = targets
            .as_object_mut()
            .unwrap()
            .insert("_type".into(), json!("root"));
        assert!(serde_json::from_value::<TargetsMetadata>(targets).is_err());
    }

    // Refuse to deserialize targets metadata with unknown spec version
    #[test]
    fn deserialize_json_targets_bad_spec_version() {
        let mut targets = make_targets();
        let _ = targets
            .as_object_mut()
            .unwrap()
            .insert("spec_version".into(), json!("0"));
        assert!(serde_json::from_value::<TargetsMetadata>(targets).is_err());
    }

    // Refuse to deserialize delegations with no keys
    #[test]
    fn deserialize_json_delegations_no_keys() {
        let mut delegations = make_delegations();
        delegations
            .as_object_mut()
            .unwrap()
            .get_mut("keys")
            .unwrap()
            .as_object_mut()
            .unwrap()
            .clear();
        assert!(serde_json::from_value::<Delegations>(delegations).is_err());
    }

    // Refuse to deserialize delegations with no roles
    #[test]
    fn deserialize_json_delegations_no_roles() {
        let mut delegations = make_delegations();
        delegations
            .as_object_mut()
            .unwrap()
            .get_mut("roles")
            .unwrap()
            .as_array_mut()
            .unwrap()
            .clear();
        assert!(serde_json::from_value::<Delegations>(delegations).is_err());
    }

    // Refuse to deserialize delegations with duplicated roles
    #[test]
    fn deserialize_json_delegations_duplicated_roles() {
        let mut delegations = make_delegations();
        let dupe = delegations
            .as_object()
            .unwrap()
            .get("roles")
            .unwrap()
            .as_array()
            .unwrap()[0]
            .clone();
        delegations
            .as_object_mut()
            .unwrap()
            .get_mut("roles")
            .unwrap()
            .as_array_mut()
            .unwrap()
            .push(dupe);
        assert!(serde_json::from_value::<Delegations>(delegations).is_err());
    }

    // Refuse to deserialize a delegation with insufficient threshold
    #[test]
    fn deserialize_json_delegation_bad_threshold() {
        let mut delegation = make_delegation();
        set_threshold(&mut delegation, 0);
        assert!(serde_json::from_value::<Delegation>(delegation).is_err());

        let mut delegation = make_delegation();
        set_threshold(&mut delegation, 2);
        assert!(serde_json::from_value::<Delegation>(delegation).is_err());
    }

    // Refuse to deserialize a delegation with duplicate key IDs
    #[test]
    fn deserialize_json_delegation_duplicate_key_ids() {
        let mut delegation = make_delegation();
        let dupe = delegation
            .as_object()
            .unwrap()
            .get("keyids")
            .unwrap()
            .as_array()
            .unwrap()[0]
            .clone();
        delegation
            .as_object_mut()
            .unwrap()
            .get_mut("keyids")
            .unwrap()
            .as_array_mut()
            .unwrap()
            .push(dupe);
        assert!(serde_json::from_value::<Delegation>(delegation).is_err());
    }

    // Refuse to deserialize a delegation with duplicate paths
    #[test]
    fn deserialize_json_delegation_duplicate_paths() {
        let mut delegation = make_delegation();
        let dupe = delegation
            .as_object()
            .unwrap()
            .get("paths")
            .unwrap()
            .as_array()
            .unwrap()[0]
            .clone();
        delegation
            .as_object_mut()
            .unwrap()
            .get_mut("paths")
            .unwrap()
            .as_array_mut()
            .unwrap()
            .push(dupe);
        assert!(serde_json::from_value::<Delegation>(delegation).is_err());
    }

    // Refuse to deserialize a Delegations struct with duplicate keys
    #[test]
    fn deserialize_json_delegations_duplicate_keys() {
        let delegations_json = r#"{
            "keys": {
                "qfrfBrkB4lBBSDEBlZgaTGS_SrE6UfmON9kP4i3dJFY=": {
                    "public_key": "MCwwBwYDK2VwBQADIQDrisJrXJ7wJ5474-giYqk7zhb-WO5CJQDTjK9GHGWjtg==",
                    "scheme": "ed25519",
                    "type": "ed25519"
                },
                "qfrfBrkB4lBBSDEBlZgaTGS_SrE6UfmON9kP4i3dJFY=": {
                    "public_key": "MCwwBwYDK2VwBQADIQDrisJrXJ7wJ5474-giYqk7zhb-WO5CJQDTjK9GHGWjtg==",
                    "scheme": "ed25519",
                    "type": "ed25519"
                }
            },
            "roles": [
            {
                "keyids": [
                    "qfrfBrkB4lBBSDEBlZgaTGS_SrE6UfmON9kP4i3dJFY="
                ],
                "paths": [
                    "bar"
                ],
                "role": "foo",
                "terminating": false,
                "threshold": 1
            }
            ]
        }"#;
        match serde_json::from_str::<Delegations>(delegations_json) {
            Err(ref err) if err.is_data() => {}
            result => panic!("unexpected result: {:?}", result),
        }
    }
}
