// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    crate::errors::{MirrorConfigError, RepositoryParseError, RepositoryUrlParseError},
    fidl_fuchsia_pkg as fidl,
    fuchsia_url::pkg_url::RepoUrl,
    http::Uri,
    http_uri_ext::HttpUriExt as _,
    serde::{Deserialize, Serialize},
    std::convert::TryFrom,
    std::{fmt, mem},
};

/// Convenience wrapper for the FIDL RepositoryStorageType.
#[derive(Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RepositoryStorageType {
    /// Store the repository in-memory. This metadata will be lost if the process or device is
    /// restarted.
    Ephemeral,

    /// Store the metadata to persitent mutable storage. This metadata will still be available if
    /// the process or device is restarted.
    Persistent,
}

/// Convenience wrapper for the FIDL RepositoryKeyConfig type
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "lowercase", tag = "type", content = "value", deny_unknown_fields)]
pub enum RepositoryKey {
    Ed25519(#[serde(with = "hex_serde")] Vec<u8>),
}

/// Convenience wrapper for the FIDL MirrorConfig type
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct MirrorConfig {
    mirror_url: http::Uri,
    subscribe: bool,
    blob_mirror_url: http::Uri,
}

impl MirrorConfig {
    // Guaranteed to always have a `scheme`.
    pub fn mirror_url(&self) -> &http::Uri {
        &self.mirror_url
    }
    pub fn subscribe(&self) -> bool {
        self.subscribe
    }

    // Guaranteed to always have a `scheme`.
    pub fn blob_mirror_url(&self) -> &http::Uri {
        &self.blob_mirror_url
    }
}

/// Omit empty optional fields and omit blob_mirror_url if derivable from mirror_url.
impl serde::Serialize for MirrorConfig {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        #[derive(Serialize)]
        pub struct SerMirrorConfig<'a> {
            #[serde(with = "uri_serde")]
            mirror_url: &'a http::Uri,
            subscribe: bool,
            #[serde(skip_serializing_if = "Option::is_none")]
            blob_mirror_url: Option<&'a str>,
        }

        let blob_mirror_url = normalize_blob_mirror_url(&self.mirror_url, &self.blob_mirror_url);
        let blob_mirror_string: String;
        let blob_mirror_url = if let Some(blob_mirror_url) = blob_mirror_url {
            blob_mirror_string = blob_mirror_url.to_string();
            Some(blob_mirror_string.as_ref())
        } else {
            None
        };
        SerMirrorConfig { mirror_url: &self.mirror_url, subscribe: self.subscribe, blob_mirror_url }
            .serialize(serializer)
    }
}

/// Derive blob_mirror_url from mirror_url if blob_mirror_url is not present.
impl<'de> serde::Deserialize<'de> for MirrorConfig {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        #[derive(Deserialize)]
        pub struct DeMirrorConfig {
            #[serde(with = "uri_serde")]
            mirror_url: http::Uri,
            subscribe: bool,
            blob_mirror_url: Option<String>,
        }

        let DeMirrorConfig { mirror_url, subscribe, blob_mirror_url } =
            DeMirrorConfig::deserialize(deserializer)?;

        if mirror_url.scheme_str().is_none() {
            return Err(serde::de::Error::custom(format!(
                "mirror_url must have a scheme: {:?}",
                mirror_url
            )));
        }

        let blob_mirror_url = if let Some(blob_mirror_url) = blob_mirror_url {
            blob_mirror_url.parse::<Uri>().map_err(|e| {
                serde::de::Error::custom(format!("bad uri string: {:?}: {}", blob_mirror_url, e))
            })?
        } else {
            blob_mirror_url_from_mirror_url(&mirror_url)
        };

        if blob_mirror_url.scheme_str().is_none() {
            return Err(serde::de::Error::custom(format!(
                "blob_mirror_url must have a scheme: {:?}",
                blob_mirror_url
            )));
        }

        Ok(Self { mirror_url, subscribe, blob_mirror_url })
    }
}

/// Convenience wrapper for generating [MirrorConfig] values.
#[derive(Clone, Debug)]
pub struct MirrorConfigBuilder {
    config: MirrorConfig,
}

impl MirrorConfigBuilder {
    pub fn new(mirror_url: impl Into<http::Uri>) -> Result<Self, MirrorConfigError> {
        let mirror_url = mirror_url.into();
        if mirror_url.scheme().is_none() {
            return Err(MirrorConfigError::MirrorUrlMissingScheme);
        }
        let blob_mirror_url = blob_mirror_url_from_mirror_url(&mirror_url);
        Ok(MirrorConfigBuilder {
            config: MirrorConfig { mirror_url, subscribe: false, blob_mirror_url },
        })
    }

    pub fn mirror_url(
        mut self,
        mirror_url: impl Into<http::Uri>,
    ) -> Result<Self, (Self, MirrorConfigError)> {
        self.config.mirror_url = mirror_url.into();
        if self.config.mirror_url.scheme().is_none() {
            return Err((self, MirrorConfigError::MirrorUrlMissingScheme));
        }
        Ok(self)
    }

    pub fn blob_mirror_url(
        mut self,
        blob_mirror_url: impl Into<http::Uri>,
    ) -> Result<Self, (Self, MirrorConfigError)> {
        self.config.blob_mirror_url = blob_mirror_url.into();
        if self.config.blob_mirror_url.scheme().is_none() {
            return Err((self, MirrorConfigError::BlobMirrorUrlMissingScheme));
        }
        Ok(self)
    }

    pub fn subscribe(mut self, subscribe: bool) -> Self {
        self.config.subscribe = subscribe;
        self
    }

    pub fn build(self) -> MirrorConfig {
        self.config
    }
}

impl From<MirrorConfigBuilder> for MirrorConfig {
    fn from(builder: MirrorConfigBuilder) -> Self {
        builder.build()
    }
}

impl TryFrom<fidl::MirrorConfig> for MirrorConfig {
    type Error = RepositoryParseError;
    fn try_from(other: fidl::MirrorConfig) -> Result<Self, RepositoryParseError> {
        let mirror_url =
            other.mirror_url.ok_or(RepositoryParseError::MirrorUrlMissing)?.parse::<Uri>()?;
        if mirror_url.scheme().is_none() {
            Err(MirrorConfigError::MirrorUrlMissingScheme)?
        }
        let blob_mirror_url = match other.blob_mirror_url {
            None => blob_mirror_url_from_mirror_url(&mirror_url),
            Some(s) => {
                let url = s.parse::<http::Uri>()?;
                if url.scheme().is_none() {
                    Err(MirrorConfigError::BlobMirrorUrlMissingScheme)?
                }
                url
            }
        };

        Ok(Self {
            mirror_url,
            subscribe: other.subscribe.ok_or(RepositoryParseError::SubscribeMissing)?,
            blob_mirror_url,
        })
    }
}

impl From<MirrorConfig> for fidl::MirrorConfig {
    fn from(config: MirrorConfig) -> Self {
        let blob_mirror_url =
            normalize_blob_mirror_url(&config.mirror_url, &config.blob_mirror_url)
                .map(|url| url.to_string());
        Self {
            mirror_url: Some(config.mirror_url.to_string()),
            subscribe: Some(config.subscribe),
            blob_mirror_url,
            ..Self::EMPTY
        }
    }
}

impl From<fidl::RepositoryStorageType> for RepositoryStorageType {
    fn from(other: fidl::RepositoryStorageType) -> Self {
        match other {
            fidl::RepositoryStorageType::Ephemeral => RepositoryStorageType::Ephemeral,
            fidl::RepositoryStorageType::Persistent => RepositoryStorageType::Persistent,
        }
    }
}

impl From<RepositoryStorageType> for fidl::RepositoryStorageType {
    fn from(storage_type: RepositoryStorageType) -> Self {
        match storage_type {
            RepositoryStorageType::Ephemeral => fidl::RepositoryStorageType::Ephemeral,
            RepositoryStorageType::Persistent => fidl::RepositoryStorageType::Persistent,
        }
    }
}

fn blob_mirror_url_from_mirror_url(mirror_url: &http::Uri) -> http::Uri {
    // Safe because mirror_url has a scheme and "blobs" is a valid path segment.
    mirror_url.to_owned().extend_dir_with_path("blobs").unwrap()
}

fn is_default_blob_mirror_url(mirror_url: &http::Uri, blob_mirror_url: &http::Uri) -> bool {
    blob_mirror_url == &blob_mirror_url_from_mirror_url(mirror_url)
}

fn normalize_blob_mirror_url<'a>(
    mirror_url: &http::Uri,
    blob_mirror_url: &'a http::Uri,
) -> Option<&'a http::Uri> {
    if is_default_blob_mirror_url(mirror_url, blob_mirror_url) {
        None
    } else {
        Some(blob_mirror_url)
    }
}

/// Convenience wrapper type for the autogenerated FIDL `RepositoryConfig`.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct RepositoryConfig {
    repo_url: RepoUrl,
    #[serde(default = "default_root_version")]
    root_version: u32,
    #[serde(default = "default_root_threshold")]
    root_threshold: u32,
    root_keys: Vec<RepositoryKey>,
    mirrors: Vec<MirrorConfig>,
    #[serde(default = "default_use_local_mirror")]
    use_local_mirror: bool,
    #[serde(default = "default_storage_type")]
    repo_storage_type: RepositoryStorageType,
}

fn default_root_version() -> u32 {
    1
}

fn default_root_threshold() -> u32 {
    1
}

fn default_use_local_mirror() -> bool {
    false
}

fn default_storage_type() -> RepositoryStorageType {
    RepositoryStorageType::Ephemeral
}

impl RepositoryConfig {
    pub fn repo_url(&self) -> &RepoUrl {
        &self.repo_url
    }

    /// Insert the provided mirror, returning any previous mirror with the same URL.
    pub fn insert_mirror(&mut self, mut mirror: MirrorConfig) -> Option<MirrorConfig> {
        if let Some(m) = self.mirrors.iter_mut().find(|m| m.mirror_url == mirror.mirror_url) {
            mem::swap(m, &mut mirror);
            Some(mirror)
        } else {
            self.mirrors.push(mirror);
            None
        }
    }

    /// Remove the requested mirror by url, returning the removed mirror, if it existed.
    pub fn remove_mirror(&mut self, mirror_url: &http::Uri) -> Option<MirrorConfig> {
        if let Some(pos) = self.mirrors.iter().position(|m| &m.mirror_url == mirror_url) {
            Some(self.mirrors.remove(pos))
        } else {
            None
        }
    }

    /// Returns a slice of all mirrors.
    pub fn mirrors(&self) -> &[MirrorConfig] {
        &self.mirrors
    }

    /// Returns the initial trusted root version.
    pub fn root_version(&self) -> u32 {
        self.root_version
    }

    /// Returns the threshold of root keys needed to sign the initial root metadata before it is
    /// considered trusted.
    pub fn root_threshold(&self) -> u32 {
        self.root_threshold
    }

    /// Returns a slice of all root keys.
    pub fn root_keys(&self) -> &[RepositoryKey] {
        &self.root_keys
    }

    pub fn use_local_mirror(&self) -> bool {
        self.use_local_mirror
    }

    /// Returns the repository storage type.
    pub fn repo_storage_type(&self) -> &RepositoryStorageType {
        &self.repo_storage_type
    }
}

impl TryFrom<fidl::RepositoryConfig> for RepositoryConfig {
    type Error = RepositoryParseError;

    fn try_from(other: fidl::RepositoryConfig) -> Result<Self, RepositoryParseError> {
        let repo_url: RepoUrl = other
            .repo_url
            .ok_or(RepositoryParseError::RepoUrlMissing)?
            .parse()
            .map_err(|err| RepositoryParseError::InvalidRepoUrl(err))?;

        let root_version = if let Some(root_version) = other.root_version {
            if root_version < 1 {
                return Err(RepositoryParseError::InvalidRootVersion(root_version));
            }
            root_version
        } else {
            1
        };

        let root_threshold = if let Some(root_threshold) = other.root_threshold {
            if root_threshold < 1 {
                return Err(RepositoryParseError::InvalidRootThreshold(root_threshold));
            }
            root_threshold
        } else {
            1
        };

        let storage_type =
            other.storage_type.map(|r| r.into()).unwrap_or(RepositoryStorageType::Ephemeral);

        Ok(Self {
            repo_url: repo_url,
            root_version: root_version,
            root_threshold: root_threshold,
            root_keys: other
                .root_keys
                .unwrap_or(vec![])
                .into_iter()
                .map(RepositoryKey::try_from)
                .collect::<Result<_, _>>()?,
            mirrors: other
                .mirrors
                .unwrap_or(vec![])
                .into_iter()
                .map(MirrorConfig::try_from)
                .collect::<Result<_, _>>()?,
            use_local_mirror: other.use_local_mirror.unwrap_or(false),
            repo_storage_type: storage_type.into(),
        })
    }
}

impl From<RepositoryConfig> for fidl::RepositoryConfig {
    fn from(config: RepositoryConfig) -> Self {
        Self {
            repo_url: Some(config.repo_url.to_string()),
            root_version: Some(config.root_version),
            root_threshold: Some(config.root_threshold),
            root_keys: Some(config.root_keys.into_iter().map(RepositoryKey::into).collect()),
            mirrors: Some(config.mirrors.into_iter().map(MirrorConfig::into).collect()),
            use_local_mirror: Some(config.use_local_mirror),
            storage_type: Some(RepositoryStorageType::into(config.repo_storage_type)),
            ..Self::EMPTY
        }
    }
}

impl From<RepositoryConfig> for RepositoryConfigBuilder {
    fn from(config: RepositoryConfig) -> Self {
        Self { config }
    }
}

/// Convenience wrapper for generating [RepositoryConfig] values.
#[derive(Clone, Debug)]
pub struct RepositoryConfigBuilder {
    config: RepositoryConfig,
}

impl RepositoryConfigBuilder {
    pub fn new(repo_url: RepoUrl) -> Self {
        RepositoryConfigBuilder {
            config: RepositoryConfig {
                repo_url,
                root_version: 1,
                root_threshold: 1,
                root_keys: vec![],
                mirrors: vec![],
                use_local_mirror: false,
                repo_storage_type: RepositoryStorageType::Ephemeral,
            },
        }
    }

    pub fn repo_url(mut self, repo_url: RepoUrl) -> Self {
        self.config.repo_url = repo_url;
        self
    }

    pub fn root_version(mut self, root_version: u32) -> Self {
        self.config.root_version = root_version;
        self
    }

    pub fn root_threshold(mut self, root_threshold: u32) -> Self {
        self.config.root_threshold = root_threshold;
        self
    }

    pub fn add_root_key(mut self, key: RepositoryKey) -> Self {
        self.config.root_keys.push(key);
        self
    }

    pub fn add_mirror(mut self, mirror: impl Into<MirrorConfig>) -> Self {
        self.config.mirrors.push(mirror.into());
        self
    }

    pub fn use_local_mirror(mut self, use_local_mirror: bool) -> Self {
        self.config.use_local_mirror = use_local_mirror;
        self
    }

    pub fn repo_storage_type(mut self, repo_storage_type: RepositoryStorageType) -> Self {
        self.config.repo_storage_type = repo_storage_type;
        self
    }

    pub fn build(self) -> RepositoryConfig {
        self.config
    }
}

impl From<RepositoryConfigBuilder> for RepositoryConfig {
    fn from(builder: RepositoryConfigBuilder) -> Self {
        builder.build()
    }
}

/// Wraper for serializing repository configs to the on-disk JSON format.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(tag = "version", content = "content", deny_unknown_fields)]
pub enum RepositoryConfigs {
    #[serde(rename = "1")]
    Version1(Vec<RepositoryConfig>),
}

impl TryFrom<fidl::RepositoryKeyConfig> for RepositoryKey {
    type Error = RepositoryParseError;
    fn try_from(id: fidl::RepositoryKeyConfig) -> Result<Self, RepositoryParseError> {
        match id {
            fidl::RepositoryKeyConfig::Ed25519Key(key) => Ok(RepositoryKey::Ed25519(key)),
            _ => Err(RepositoryParseError::UnsupportedKeyType),
        }
    }
}

impl From<RepositoryKey> for fidl::RepositoryKeyConfig {
    fn from(key: RepositoryKey) -> Self {
        match key {
            RepositoryKey::Ed25519(key) => fidl::RepositoryKeyConfig::Ed25519Key(key),
        }
    }
}

impl fmt::Debug for RepositoryKey {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let RepositoryKey::Ed25519(ref value) = self;
        f.debug_tuple("Ed25519").field(&hex::encode(value)).finish()
    }
}

#[derive(Debug, PartialEq, Clone)]
/// Convenience wrapper type for the autogenerated FIDL `RepositoryUrl`.
pub struct RepositoryUrl {
    url: RepoUrl,
}

impl RepositoryUrl {
    pub fn url(&self) -> &RepoUrl {
        &self.url
    }
}

impl From<RepoUrl> for RepositoryUrl {
    fn from(url: RepoUrl) -> Self {
        Self { url }
    }
}

impl TryFrom<&fidl::RepositoryUrl> for RepositoryUrl {
    type Error = RepositoryUrlParseError;

    fn try_from(other: &fidl::RepositoryUrl) -> Result<Self, RepositoryUrlParseError> {
        Ok(Self { url: other.url.parse().map_err(RepositoryUrlParseError::InvalidRepoUrl)? })
    }
}

impl From<RepositoryUrl> for fidl::RepositoryUrl {
    fn from(url: RepositoryUrl) -> Self {
        Self { url: url.url.to_string() }
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*, assert_matches::assert_matches, proptest::prelude::*, serde_json::json,
        std::convert::TryInto,
    };
    fn verify_json_serde<T>(expected_value: T, expected_json: serde_json::Value)
    where
        T: PartialEq + std::fmt::Debug,
        T: serde::Serialize,
        for<'de> T: serde::Deserialize<'de>,
    {
        let actual_json = serde_json::to_value(&expected_value).expect("value to serialize");
        assert_eq!(actual_json, expected_json);
        let actual_value = serde_json::from_value::<T>(actual_json).expect("json to deserialize");
        assert_eq!(actual_value, expected_value);
    }

    #[test]
    fn test_repository_key_serde() {
        verify_json_serde(
            RepositoryKey::Ed25519(vec![0xf1, 15, 16, 3]),
            json!({
                "type": "ed25519",
                "value": "f10f1003",
            }),
        );
        verify_json_serde(
            RepositoryKey::Ed25519(vec![0, 1, 2, 3]),
            json!({
                "type": "ed25519",
                "value": "00010203",
            }),
        );
    }

    #[test]
    fn test_repository_key_deserialize_with_bad_type() {
        let json = r#"{"type":"bogus","value":"00010203"}"#;
        let result = serde_json::from_str::<RepositoryKey>(json);
        let error_message = result.unwrap_err().to_string();
        assert!(
            error_message.contains("unknown variant `bogus`"),
            r#"Error message did not contain "unknown variant `bogus`", was "{}""#,
            error_message
        );
    }

    #[test]
    fn test_repository_key_into_fidl() {
        let key = RepositoryKey::Ed25519(vec![0xf1, 15, 16, 3]);
        let as_fidl: fidl::RepositoryKeyConfig = key.into();
        assert_eq!(as_fidl, fidl::RepositoryKeyConfig::Ed25519Key(vec![0xf1, 15, 16, 3]))
    }

    #[test]
    fn test_repository_key_from_fidl() {
        let as_fidl = fidl::RepositoryKeyConfig::Ed25519Key(vec![0xf1, 15, 16, 3]);
        assert_matches!(
            RepositoryKey::try_from(as_fidl),
            Ok(RepositoryKey::Ed25519(v)) if v == vec![0xf1, 15, 16, 3]
        );
    }

    #[test]
    fn test_repository_key_from_fidl_with_bad_type() {
        let as_fidl = fidl::RepositoryKeyConfig::unknown(999, Default::default());
        assert_matches!(
            RepositoryKey::try_from(as_fidl),
            Err(RepositoryParseError::UnsupportedKeyType)
        );
    }

    #[test]
    fn test_repository_key_into_from_fidl_roundtrip() {
        let key = RepositoryKey::Ed25519(vec![0xf1, 15, 16, 3]);
        let as_fidl: fidl::RepositoryKeyConfig = key.clone().into();
        assert_eq!(RepositoryKey::try_from(as_fidl).unwrap(), key,)
    }

    #[test]
    fn test_mirror_config_serde() {
        verify_json_serde(
            MirrorConfigBuilder::new("http://example.com/".parse::<Uri>().unwrap())
                .unwrap()
                .build(),
            json!({
                "mirror_url": "http://example.com/",
                "subscribe": false,
            }),
        );

        verify_json_serde(
            MirrorConfigBuilder::new("http://example.com".parse::<Uri>().unwrap())
                .unwrap()
                .blob_mirror_url("http://example.com/subdir".parse::<Uri>().unwrap())
                .unwrap()
                .build(),
            json!({
                "mirror_url": "http://example.com/",
                "blob_mirror_url": "http://example.com/subdir",
                "subscribe": false,
            }),
        );

        verify_json_serde(
            MirrorConfigBuilder::new("http://example.com".parse::<Uri>().unwrap())
                .unwrap()
                .blob_mirror_url("http://example.com/blobs".parse::<Uri>().unwrap())
                .unwrap()
                .build(),
            json!({
                "mirror_url": "http://example.com/",
                "subscribe": false,
            }),
        );

        verify_json_serde(
            MirrorConfigBuilder::new("http://example.com".parse::<Uri>().unwrap())
                .unwrap()
                .subscribe(true)
                .build(),
            json!({
                "mirror_url": "http://example.com/",
                "subscribe": true,
            }),
        );

        {
            // A mirror config with a previously-accepted "blob_key" still parses.
            let json = json!({
                "mirror_url": "http://example.com/",
                "blob_key": {
                    "type": "aes",
                    "value": "00010203",
                },
                "subscribe": false,
            });
            assert_eq!(
                serde_json::from_value::<MirrorConfig>(json).expect("json to deserialize"),
                MirrorConfigBuilder::new("http://example.com".parse::<Uri>().unwrap())
                    .unwrap()
                    .build()
            );
        }
    }

    #[test]
    fn test_mirror_config_deserialize_rejects_urls_without_schemes() {
        let j = json!({
            "mirror_url": "example.com",
            "subscribe": false,
        });
        assert_matches!(
            serde_json::from_value::<MirrorConfig>(j),
            Err(e) if e.to_string().starts_with("mirror_url must have a scheme")
        );

        let j = json!({
            "mirror_url": "https://example.com",
            "subscribe": false,
            "blob_mirror_url": Some("example.com")
        });
        assert_matches!(
            serde_json::from_value::<MirrorConfig>(j),
            Err(e) if e.to_string().starts_with("blob_mirror_url must have a scheme")
        );
    }

    #[test]
    fn test_mirror_config_into_fidl() {
        let config = MirrorConfig {
            mirror_url: "http://example.com/tuf/repo".parse::<Uri>().unwrap(),
            subscribe: true,
            blob_mirror_url: "http://example.com/tuf/repo/subdir/blobs".parse::<Uri>().unwrap(),
        };
        let as_fidl: fidl::MirrorConfig = config.into();
        assert_eq!(
            as_fidl,
            fidl::MirrorConfig {
                mirror_url: Some("http://example.com/tuf/repo".into()),
                subscribe: Some(true),
                blob_mirror_url: Some("http://example.com/tuf/repo/subdir/blobs".into()),
                ..fidl::MirrorConfig::EMPTY
            }
        );
    }

    #[test]
    fn test_mirror_config_into_fidl_normalizes_blob_mirror_url() {
        let config = MirrorConfig {
            mirror_url: "http://example.com/tuf/repo".parse::<Uri>().unwrap(),
            subscribe: false,
            blob_mirror_url: "http://example.com/tuf/repo/blobs".parse::<Uri>().unwrap(),
        };
        let as_fidl: fidl::MirrorConfig = config.into();
        assert_eq!(
            as_fidl,
            fidl::MirrorConfig {
                mirror_url: Some("http://example.com/tuf/repo".into()),
                subscribe: Some(false),
                blob_mirror_url: None,
                ..fidl::MirrorConfig::EMPTY
            }
        );
    }

    #[test]
    fn test_mirror_config_from_fidl() {
        let as_fidl = fidl::MirrorConfig {
            mirror_url: Some("http://example.com/tuf/repo".into()),
            subscribe: Some(true),
            blob_mirror_url: Some("http://example.com/tuf/repo/subdir/blobs".into()),
            ..fidl::MirrorConfig::EMPTY
        };
        assert_matches!(
            MirrorConfig::try_from(as_fidl),
            Ok(mirror_config) if mirror_config == MirrorConfig {
                mirror_url: "http://example.com/tuf/repo".parse::<Uri>().unwrap(),
                subscribe: true,
                blob_mirror_url: "http://example.com/tuf/repo/subdir/blobs".parse::<Uri>().unwrap(),
            }
        );
    }

    #[test]
    fn test_mirror_config_from_fidl_rejects_urls_without_schemes() {
        let as_fidl = fidl::MirrorConfig {
            mirror_url: Some("example.com".into()),
            subscribe: Some(false),
            blob_mirror_url: None,
            ..fidl::MirrorConfig::EMPTY
        };
        assert_matches!(
            MirrorConfig::try_from(as_fidl),
            Err(RepositoryParseError::MirrorConfig(MirrorConfigError::MirrorUrlMissingScheme))
        );

        let as_fidl = fidl::MirrorConfig {
            mirror_url: Some("https://example.com".into()),
            subscribe: Some(false),
            blob_mirror_url: Some("example.com".into()),
            ..fidl::MirrorConfig::EMPTY
        };
        assert_matches!(
            MirrorConfig::try_from(as_fidl),
            Err(RepositoryParseError::MirrorConfig(MirrorConfigError::BlobMirrorUrlMissingScheme))
        );
    }

    #[test]
    fn test_mirror_config_from_fidl_populates_blob_mirror_url() {
        let as_fidl = fidl::MirrorConfig {
            mirror_url: Some("http://example.com/tuf/repo/".into()),
            subscribe: Some(false),
            blob_mirror_url: None,
            ..fidl::MirrorConfig::EMPTY
        };
        assert_matches!(
            MirrorConfig::try_from(as_fidl),
            Ok(mirror_config) if mirror_config == MirrorConfig {
                mirror_url: "http://example.com/tuf/repo/".parse::<Uri>().unwrap(),
                subscribe: false,
                blob_mirror_url: "http://example.com/tuf/repo/blobs".parse::<Uri>().unwrap(),
            }
        );
    }

    prop_compose! {
        fn uri_with_adversarial_path()(path in "[p/]{0,6}") -> http::Uri
        {
            let mut parts = http::uri::Parts::default();
            parts.scheme = Some(http::uri::Scheme::HTTP);
            parts.authority = Some(http::uri::Authority::from_static("example.com"));
            parts.path_and_query = Some(path.parse().unwrap());
            http::Uri::from_parts(parts).unwrap()
        }
    }

    proptest! {
        #[test]
        fn blob_mirror_url_from_mirror_url_produces_default_blob_mirror_urls(
            mirror_url in uri_with_adversarial_path()
        ) {
            let blob_mirror_url = blob_mirror_url_from_mirror_url(&mirror_url);
            prop_assert!(is_default_blob_mirror_url(&mirror_url, &blob_mirror_url));
        }

        #[test]
        fn normalize_blob_mirror_url_detects_default_blob_mirror_url(
            mirror_url in uri_with_adversarial_path()
        ) {
            let blob_mirror_url = blob_mirror_url_from_mirror_url(&mirror_url);
            prop_assert_eq!(normalize_blob_mirror_url(&mirror_url, &blob_mirror_url), None);
            // also, swapped parameters should never return None
            prop_assert_ne!(normalize_blob_mirror_url(&blob_mirror_url, &mirror_url), None);
        }
    }

    #[test]
    fn test_mirror_config_into_from_fidl_roundtrip() {
        let config = MirrorConfig {
            mirror_url: "http://example.com/tuf/repo/".parse::<Uri>().unwrap(),
            subscribe: true,
            blob_mirror_url: "http://example.com/tuf/repo/blobs".parse::<Uri>().unwrap(),
        };
        let as_fidl: fidl::MirrorConfig = config.clone().into();
        assert_eq!(MirrorConfig::try_from(as_fidl).unwrap(), config);
    }

    #[test]
    fn test_mirror_config_builder() {
        let builder =
            MirrorConfigBuilder::new("http://example.com/".parse::<Uri>().unwrap()).unwrap();
        assert_eq!(
            builder.clone().build(),
            MirrorConfig {
                mirror_url: "http://example.com/".parse::<Uri>().unwrap(),
                subscribe: false,
                blob_mirror_url: "http://example.com/blobs".parse::<Uri>().unwrap(),
            }
        );
        assert_eq!(
            builder
                .clone()
                .blob_mirror_url("http://example.com/a/b".parse::<Uri>().unwrap())
                .unwrap()
                .build(),
            MirrorConfig {
                mirror_url: "http://example.com/".parse::<Uri>().unwrap(),
                subscribe: false,
                blob_mirror_url: "http://example.com/a/b".parse::<Uri>().unwrap(),
            }
        );
        assert_eq!(
            builder.clone().mirror_url("http://127.0.0.1".parse::<Uri>().unwrap()).unwrap().build(),
            MirrorConfig {
                mirror_url: "http://127.0.0.1".parse::<Uri>().unwrap(),
                subscribe: false,
                blob_mirror_url: "http://example.com/blobs".parse::<Uri>().unwrap(),
            }
        );
        assert_eq!(
            builder.subscribe(true).build(),
            MirrorConfig {
                mirror_url: "http://example.com".parse::<Uri>().unwrap(),
                subscribe: true,
                blob_mirror_url: "http://example.com/blobs".parse::<Uri>().unwrap(),
            }
        );
    }

    #[test]
    fn test_mirror_config_builder_rejects_urls_without_schemes() {
        assert_matches!(
            MirrorConfigBuilder::new("example.com".parse::<Uri>().unwrap()),
            Err(MirrorConfigError::MirrorUrlMissingScheme)
        );

        let builder =
            MirrorConfigBuilder::new("http://example.com/".parse::<Uri>().unwrap()).unwrap();
        assert_matches!(
            builder.mirror_url("example.com".parse::<Uri>().unwrap()),
            Err((_, MirrorConfigError::MirrorUrlMissingScheme))
        );

        let builder =
            MirrorConfigBuilder::new("http://example.com/".parse::<Uri>().unwrap()).unwrap();
        assert_matches!(
            builder.blob_mirror_url("example.com".parse::<Uri>().unwrap()),
            Err((_, MirrorConfigError::BlobMirrorUrlMissingScheme))
        );
    }

    #[test]
    fn test_mirror_config_bad_uri() {
        let as_fidl = fidl::MirrorConfig {
            mirror_url: None,
            subscribe: Some(false),
            blob_mirror_url: None,
            ..fidl::MirrorConfig::EMPTY
        };
        assert_matches!(
            MirrorConfig::try_from(as_fidl),
            Err(RepositoryParseError::MirrorUrlMissing)
        );
    }

    #[test]
    fn test_repository_config_builder() {
        let repo_url = RepoUrl::parse("fuchsia-pkg://fuchsia.com").unwrap();
        let builder = RepositoryConfigBuilder::new(repo_url.clone());
        assert_eq!(
            builder.clone().build(),
            RepositoryConfig {
                repo_url: repo_url.clone(),
                root_version: 1,
                root_threshold: 1,
                root_keys: vec![],
                mirrors: vec![],
                use_local_mirror: false,
                repo_storage_type: RepositoryStorageType::Ephemeral,
            }
        );

        assert_eq!(
            builder.clone().repo_storage_type(RepositoryStorageType::Persistent).build(),
            RepositoryConfig {
                repo_url: repo_url.clone(),
                root_version: 1,
                root_threshold: 1,
                root_keys: vec![],
                mirrors: vec![],
                use_local_mirror: false,
                repo_storage_type: RepositoryStorageType::Persistent,
            }
        );
    }

    #[test]
    fn test_repository_config_into_fidl() {
        let config = RepositoryConfig {
            repo_url: "fuchsia-pkg://fuchsia.com".try_into().unwrap(),
            root_version: 2,
            root_threshold: 2,
            root_keys: vec![RepositoryKey::Ed25519(vec![0xf1, 15, 16, 3])],
            mirrors: vec![MirrorConfig {
                mirror_url: "http://example.com/tuf/repo".parse::<Uri>().unwrap(),
                subscribe: true,
                blob_mirror_url: "http://example.com/tuf/repo/blobs".parse::<Uri>().unwrap(),
            }],
            use_local_mirror: true,
            repo_storage_type: RepositoryStorageType::Ephemeral,
        };
        let as_fidl: fidl::RepositoryConfig = config.into();
        assert_eq!(
            as_fidl,
            fidl::RepositoryConfig {
                repo_url: Some("fuchsia-pkg://fuchsia.com".try_into().unwrap()),
                root_version: Some(2),
                root_threshold: Some(2),
                root_keys: Some(vec![fidl::RepositoryKeyConfig::Ed25519Key(vec![0xf1, 15, 16, 3])]),
                mirrors: Some(vec![fidl::MirrorConfig {
                    mirror_url: Some("http://example.com/tuf/repo".into()),
                    subscribe: Some(true),
                    blob_mirror_url: None,
                    ..fidl::MirrorConfig::EMPTY
                }]),
                use_local_mirror: Some(true),
                storage_type: Some(fidl::RepositoryStorageType::Ephemeral),
                ..fidl::RepositoryConfig::EMPTY
            }
        );
    }

    #[test]
    fn test_repository_config_from_fidl_without_storage_type() {
        let as_fidl = fidl::RepositoryConfig {
            repo_url: Some("fuchsia-pkg://fuchsia.com".try_into().unwrap()),
            root_version: Some(1),
            root_threshold: Some(1),
            root_keys: Some(vec![fidl::RepositoryKeyConfig::Ed25519Key(vec![0xf1, 15, 16, 3])]),
            mirrors: Some(vec![fidl::MirrorConfig {
                mirror_url: Some("http://example.com/tuf/repo/".into()),
                subscribe: Some(true),
                blob_mirror_url: None,
                ..fidl::MirrorConfig::EMPTY
            }]),
            use_local_mirror: None,
            storage_type: None,
            ..fidl::RepositoryConfig::EMPTY
        };
        assert_matches!(
            RepositoryConfig::try_from(as_fidl),
            Ok(repository_config) if repository_config == RepositoryConfig {
                repo_url: "fuchsia-pkg://fuchsia.com".try_into().unwrap(),
                root_version: 1,
                root_threshold: 1,
                root_keys: vec![RepositoryKey::Ed25519(vec![0xf1, 15, 16, 3]),],
                mirrors: vec![MirrorConfig {
                    mirror_url: "http://example.com/tuf/repo/".parse::<Uri>().unwrap(),
                    subscribe: true,
                    blob_mirror_url: "http://example.com/tuf/repo/blobs".parse::<Uri>().unwrap(),
                },],
                use_local_mirror: false,
                repo_storage_type: RepositoryStorageType::Ephemeral,
            }
        );
    }

    #[test]
    fn test_repository_config_from_fidl_with_storage_type() {
        let as_fidl = fidl::RepositoryConfig {
            repo_url: Some("fuchsia-pkg://fuchsia.com".try_into().unwrap()),
            root_version: Some(1),
            root_threshold: Some(1),
            root_keys: Some(vec![fidl::RepositoryKeyConfig::Ed25519Key(vec![0xf1, 15, 16, 3])]),
            mirrors: Some(vec![fidl::MirrorConfig {
                mirror_url: Some("http://example.com/tuf/repo/".into()),
                subscribe: Some(true),
                blob_mirror_url: None,
                ..fidl::MirrorConfig::EMPTY
            }]),
            use_local_mirror: None,
            storage_type: Some(fidl::RepositoryStorageType::Persistent),
            ..fidl::RepositoryConfig::EMPTY
        };
        assert_matches!(
            RepositoryConfig::try_from(as_fidl),
            Ok(repository_config) if repository_config == RepositoryConfig {
                repo_url: "fuchsia-pkg://fuchsia.com".try_into().unwrap(),
                root_version: 1,
                root_threshold: 1,
                root_keys: vec![RepositoryKey::Ed25519(vec![0xf1, 15, 16, 3]),],
                mirrors: vec![MirrorConfig {
                    mirror_url: "http://example.com/tuf/repo/".parse::<Uri>().unwrap(),
                    subscribe: true,
                    blob_mirror_url: "http://example.com/tuf/repo/blobs".parse::<Uri>().unwrap(),
                },],
                use_local_mirror: false,
                repo_storage_type: RepositoryStorageType::Persistent,
            }
        );
    }

    #[test]
    fn test_repository_config_from_fidl_without_version_and_threshold_and_use_local_mirror() {
        let as_fidl = fidl::RepositoryConfig {
            repo_url: Some("fuchsia-pkg://fuchsia.com".try_into().unwrap()),
            root_version: None,
            root_threshold: None,
            root_keys: Some(vec![fidl::RepositoryKeyConfig::Ed25519Key(vec![0xf1, 15, 16, 3])]),
            mirrors: Some(vec![fidl::MirrorConfig {
                mirror_url: Some("http://example.com/tuf/repo/".into()),
                subscribe: Some(true),
                blob_mirror_url: None,
                ..fidl::MirrorConfig::EMPTY
            }]),
            use_local_mirror: None,
            storage_type: None,
            ..fidl::RepositoryConfig::EMPTY
        };
        assert_matches!(
            RepositoryConfig::try_from(as_fidl),
            Ok(repository_config) if repository_config == RepositoryConfig {
                repo_url: "fuchsia-pkg://fuchsia.com".try_into().unwrap(),
                root_version: 1,
                root_threshold: 1,
                root_keys: vec![RepositoryKey::Ed25519(vec![0xf1, 15, 16, 3]),],
                mirrors: vec![MirrorConfig {
                    mirror_url: "http://example.com/tuf/repo/".parse::<Uri>().unwrap(),
                    subscribe: true,
                    blob_mirror_url: "http://example.com/tuf/repo/blobs".parse::<Uri>().unwrap(),
                },],
                use_local_mirror: false,
                repo_storage_type: RepositoryStorageType::Ephemeral,
            }
        );
    }

    #[test]
    fn test_repository_config_from_fidl_with_version_and_threshold_and_use_local_mirror() {
        let as_fidl = fidl::RepositoryConfig {
            repo_url: Some("fuchsia-pkg://fuchsia.com".try_into().unwrap()),
            root_version: Some(2),
            root_threshold: Some(2),
            root_keys: Some(vec![fidl::RepositoryKeyConfig::Ed25519Key(vec![0xf1, 15, 16, 3])]),
            mirrors: Some(vec![fidl::MirrorConfig {
                mirror_url: Some("http://example.com/tuf/repo/".into()),
                subscribe: Some(true),
                blob_mirror_url: None,
                ..fidl::MirrorConfig::EMPTY
            }]),
            use_local_mirror: Some(true),
            storage_type: None,
            ..fidl::RepositoryConfig::EMPTY
        };
        assert_matches!(
            RepositoryConfig::try_from(as_fidl),
            Ok(repository_config) if repository_config == RepositoryConfig {
                repo_url: "fuchsia-pkg://fuchsia.com".try_into().unwrap(),
                root_version: 2,
                root_threshold: 2,
                root_keys: vec![RepositoryKey::Ed25519(vec![0xf1, 15, 16, 3]),],
                mirrors: vec![MirrorConfig {
                    mirror_url: "http://example.com/tuf/repo/".parse::<Uri>().unwrap(),
                    subscribe: true,
                    blob_mirror_url: "http://example.com/tuf/repo/blobs".parse::<Uri>().unwrap(),
                },],
                use_local_mirror: true,
                repo_storage_type: RepositoryStorageType::Ephemeral,
            }
        );
    }

    #[test]
    fn test_repository_config_from_fidl_repo_url_missing() {
        let as_fidl = fidl::RepositoryConfig {
            repo_url: None,
            root_version: None,
            root_threshold: None,
            root_keys: Some(vec![]),
            mirrors: Some(vec![]),
            use_local_mirror: None,
            storage_type: None,
            ..fidl::RepositoryConfig::EMPTY
        };
        assert_matches!(
            RepositoryConfig::try_from(as_fidl),
            Err(RepositoryParseError::RepoUrlMissing)
        );
    }

    #[test]
    fn test_repository_config_into_from_fidl_roundtrip() {
        let config = RepositoryConfig {
            repo_url: "fuchsia-pkg://fuchsia.com".try_into().unwrap(),
            root_version: 2,
            root_threshold: 2,
            root_keys: vec![RepositoryKey::Ed25519(vec![0xf1, 15, 16, 3])],
            mirrors: vec![MirrorConfig {
                mirror_url: "http://example.com/tuf/repo/".parse::<Uri>().unwrap(),
                subscribe: true,
                blob_mirror_url: "http://example.com/tuf/repo/blobs".parse::<Uri>().unwrap(),
            }],
            use_local_mirror: true,
            repo_storage_type: RepositoryStorageType::Ephemeral,
        };
        let as_fidl: fidl::RepositoryConfig = config.clone().into();
        assert_eq!(RepositoryConfig::try_from(as_fidl).unwrap(), config);
    }

    #[test]
    fn test_repository_config_deserialize_missing_root_version_and_threshold_and_use_local_mirror()
    {
        let json_value = json!({
            "repo_url": "fuchsia-pkg://fuchsia.com",
            "root_keys": [],
            "mirrors": [],
        });
        let actual_config: RepositoryConfig = serde_json::from_value(json_value).unwrap();

        assert_eq!(
            actual_config,
            RepositoryConfig {
                repo_url: "fuchsia-pkg://fuchsia.com".try_into().unwrap(),
                root_version: 1,
                root_threshold: 1,
                root_keys: vec![],
                mirrors: vec![],
                use_local_mirror: false,
                repo_storage_type: RepositoryStorageType::Ephemeral,
            },
        );
    }

    // Validate we can still deserialize old configs that have the now-removed
    // "update_package_url" field.
    #[test]
    fn test_repository_config_deserialize_ignores_update_package_url() {
        let json_value = json!({
            "repo_url": "fuchsia-pkg://fuchsia.com",
            "root_keys": [],
            "mirrors": [],
            "update_package_url": "ignored-value",
        });
        let actual_config: RepositoryConfig = serde_json::from_value(json_value).unwrap();

        assert_eq!(
            actual_config,
            RepositoryConfig {
                repo_url: "fuchsia-pkg://fuchsia.com".try_into().unwrap(),
                root_version: 1,
                root_threshold: 1,
                root_keys: vec![],
                mirrors: vec![],
                use_local_mirror: false,
                repo_storage_type: RepositoryStorageType::Ephemeral,
            },
        );
    }

    #[test]
    fn test_repository_configs_serde_simple() {
        verify_json_serde(
            RepositoryConfigs::Version1(vec![RepositoryConfig {
                repo_url: "fuchsia-pkg://fuchsia.com".try_into().unwrap(),
                root_version: 1,
                root_threshold: 1,
                root_keys: vec![],
                mirrors: vec![],
                use_local_mirror: true,
                repo_storage_type: RepositoryStorageType::Ephemeral,
            }]),
            json!({
                "version": "1",
                "content": [{
                    "repo_url": "fuchsia-pkg://fuchsia.com",
                    "root_version": 1,
                    "root_threshold": 1,
                    "root_keys": [],
                    "mirrors": [],
                    "use_local_mirror": true,
                    "repo_storage_type": "ephemeral",
                }],
            }),
        );
    }

    #[test]
    fn test_repository_url_into_fidl() {
        let url = RepositoryUrl { url: "fuchsia-pkg://fuchsia.com".parse().unwrap() };
        let as_fidl: fidl::RepositoryUrl = url.into();
        assert_eq!(as_fidl, fidl::RepositoryUrl { url: "fuchsia-pkg://fuchsia.com".to_owned() });
    }

    #[test]
    fn test_repository_url_from_fidl() {
        let as_fidl = fidl::RepositoryUrl { url: "fuchsia-pkg://fuchsia.com".to_owned() };
        assert_matches!(
            RepositoryUrl::try_from(&as_fidl),
            Ok(RepositoryUrl { url }) if url == "fuchsia-pkg://fuchsia.com".parse().unwrap()
        );
    }

    #[test]
    fn test_repository_url_from_fidl_with_bad_url() {
        let as_fidl = fidl::RepositoryUrl { url: "invalid-scheme://fuchsia.com".to_owned() };
        assert_matches!(
            RepositoryUrl::try_from(&as_fidl),
            Err(RepositoryUrlParseError::InvalidRepoUrl(
                fuchsia_url::pkg_url::ParseError::InvalidScheme
            ))
        );
    }

    #[test]
    fn test_repository_url_into_from_fidl_roundtrip() {
        let url = RepositoryUrl { url: "fuchsia-pkg://fuchsia.com".parse().unwrap() };
        let as_fidl: fidl::RepositoryUrl = url.clone().into();
        assert_eq!(RepositoryUrl::try_from(&as_fidl).unwrap(), url);
    }
}

mod hex_serde {
    use {hex, serde::Deserialize};

    pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let s = hex::encode(bytes);
        serializer.serialize_str(&s)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let value = String::deserialize(deserializer)?;
        hex::decode(value.as_bytes())
            .map_err(|e| serde::de::Error::custom(format!("bad hex value: {:?}: {}", value, e)))
    }
}

mod uri_serde {
    use {http::Uri, serde::Deserialize};

    pub fn serialize<S>(uri: &http::Uri, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let s = uri.to_string();
        serializer.serialize_str(&s)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<http::Uri, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let value = String::deserialize(deserializer)?;
        value
            .parse::<Uri>()
            .map_err(|e| serde::de::Error::custom(format!("bad uri value: {:?}: {}", value, e)))
    }
}
