// 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 {
    failure::{format_err, Error},
    fidl_fuchsia_amber as fidl,
    serde_derive::{Deserialize, Serialize},
    std::{
        convert::{TryFrom, TryInto},
        fmt,
    },
};

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct SourceConfigBuilder {
    config: SourceConfig,
}

impl SourceConfigBuilder {
    pub fn new(id: impl Into<String>) -> Self {
        Self {
            config: SourceConfig {
                id: id.into(),
                repo_url: "".to_string(),
                blob_repo_url: "".to_string(),
                rate_limit: 0,
                rate_period: 0,
                root_keys: vec![],
                transport_config: None,
                status_config: Some(StatusConfig { enabled: true }),
                auto: false,
                blob_key: None,
            },
        }
    }

    pub fn repo_url(mut self, value: impl Into<String>) -> Self {
        self.config.repo_url = value.into();
        self.config.blob_repo_url = format!("{}/blobs", self.config.repo_url);
        self
    }

    pub fn rate_period(mut self, value: i32) -> Self {
        self.config.rate_period = value;
        self
    }

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

    pub fn add_root_key(mut self, value: &str) -> Self {
        self.config.root_keys.push(KeyConfig::Ed25519(hex::decode(value).unwrap()));
        self
    }

    pub fn enabled(mut self, enabled: bool) -> Self {
        self.config.status_config = Some(StatusConfig { enabled });
        self
    }

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

#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SourceConfig {
    id: String,
    #[serde(rename = "repoURL")]
    repo_url: String,
    #[serde(rename = "blobRepoURL")]
    blob_repo_url: String,
    #[serde(default, rename = "rateLimit")]
    rate_limit: u64,
    #[serde(default, rename = "ratePeriod")]
    rate_period: i32,
    #[serde(rename = "rootKeys")]
    root_keys: Vec<KeyConfig>,
    #[serde(rename = "transportConfig")]
    transport_config: Option<TransportConfig>,
    #[serde(rename = "statusConfig")]
    status_config: Option<StatusConfig>,
    auto: bool,
    #[serde(rename = "blobKey")]
    blob_key: Option<BlobEncryptionKey>,
}

impl SourceConfig {
    pub fn id(&self) -> &str {
        self.id.as_str()
    }
}

impl Into<fidl::SourceConfig> for SourceConfig {
    fn into(self) -> fidl::SourceConfig {
        fidl::SourceConfig {
            id: self.id,
            repo_url: self.repo_url,
            blob_repo_url: self.blob_repo_url,
            rate_limit: self.rate_limit,
            rate_period: self.rate_period,
            root_keys: self.root_keys.into_iter().map(|key| key.into()).collect(),
            transport_config: self.transport_config.map(|cfg| Box::new(cfg.into())),
            oauth2_config: None,
            status_config: self.status_config.map(|cfg| Box::new(cfg.into())),
            auto: self.auto,
            blob_key: self.blob_key.map(|key| Box::new(key.into())),
        }
    }
}

impl TryFrom<fidl::SourceConfig> for SourceConfig {
    type Error = Error;
    fn try_from(x: fidl::SourceConfig) -> Result<Self, Self::Error> {
        if x.oauth2_config.is_some() {
            return Err(format_err!("oauth2_config is not supported"));
        }
        Ok(SourceConfig {
            id: x.id,
            repo_url: x.repo_url,
            blob_repo_url: x.blob_repo_url,
            rate_limit: x.rate_limit,
            rate_period: x.rate_period,
            root_keys: x
                .root_keys
                .into_iter()
                .map(|key| key.try_into())
                .collect::<Result<Vec<_>, _>>()?,
            transport_config: x.transport_config.map(|cfg| cfg.try_into()).transpose()?,
            status_config: x.status_config.map(|cfg| cfg.try_into()).transpose()?,
            auto: x.auto,
            blob_key: x.blob_key.map(|key| key.try_into()).transpose()?,
        })
    }
}

impl Ord for SourceConfig {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.id.cmp(&other.id)
    }
}

impl PartialOrd for SourceConfig {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TransportConfig {
    disable_keep_alives: bool,
    keep_alive: i32,
    max_idle_conns: i32,
    max_idle_conns_per_host: i32,
    connect_timeout: i32,
    request_timeout: i32,
    idle_conn_timeout: i32,
    response_header_timeout: i32,
    expect_continue_timeout: i32,
    tls_handshake_timeout: i32,
}

impl Into<fidl::TransportConfig> for TransportConfig {
    fn into(self) -> fidl::TransportConfig {
        fidl::TransportConfig {
            disable_keep_alives: self.disable_keep_alives,
            keep_alive: self.keep_alive,
            max_idle_conns: self.max_idle_conns,
            max_idle_conns_per_host: self.max_idle_conns_per_host,
            connect_timeout: self.connect_timeout,
            request_timeout: self.request_timeout,
            idle_conn_timeout: self.idle_conn_timeout,
            response_header_timeout: self.response_header_timeout,
            expect_continue_timeout: self.expect_continue_timeout,
            tls_handshake_timeout: self.tls_handshake_timeout,
            tls_client_config: None,
        }
    }
}

impl TryFrom<Box<fidl::TransportConfig>> for TransportConfig {
    type Error = Error;
    fn try_from(x: Box<fidl::TransportConfig>) -> Result<Self, Self::Error> {
        if x.tls_client_config.is_some() {
            return Err(format_err!("tls_client_config not supported"));
        }
        Ok(TransportConfig {
            disable_keep_alives: x.disable_keep_alives,
            keep_alive: x.keep_alive,
            max_idle_conns: x.max_idle_conns,
            max_idle_conns_per_host: x.max_idle_conns_per_host,
            connect_timeout: x.connect_timeout,
            request_timeout: x.request_timeout,
            idle_conn_timeout: x.idle_conn_timeout,
            response_header_timeout: x.response_header_timeout,
            expect_continue_timeout: x.expect_continue_timeout,
            tls_handshake_timeout: x.tls_handshake_timeout,
        })
    }
}

#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase", tag = "type", content = "value", deny_unknown_fields)]
pub enum KeyConfig {
    Ed25519(#[serde(with = "hex_serde")] Vec<u8>),
}

impl Into<fidl::KeyConfig> for KeyConfig {
    fn into(self) -> fidl::KeyConfig {
        let KeyConfig::Ed25519(value) = self;
        fidl::KeyConfig { type_: "ed25519".to_owned(), value: hex::encode(value) }
    }
}

impl TryFrom<fidl::KeyConfig> for KeyConfig {
    type Error = Error;
    fn try_from(x: fidl::KeyConfig) -> Result<Self, Self::Error> {
        if x.type_ != "ed25519" {
            return Err(format_err!("unknown key type: {}", x.type_));
        }
        Ok(KeyConfig::Ed25519(hex::decode(x.value.as_bytes())?))
    }
}

impl fmt::Debug for KeyConfig {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let KeyConfig::Ed25519(ref value) = self;
        f.write_str(&hex::encode(value))
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct StatusConfig {
    enabled: bool,
}

impl Into<fidl::StatusConfig> for StatusConfig {
    fn into(self) -> fidl::StatusConfig {
        fidl::StatusConfig { enabled: self.enabled }
    }
}

impl TryFrom<Box<fidl::StatusConfig>> for StatusConfig {
    type Error = Error;
    fn try_from(x: Box<fidl::StatusConfig>) -> Result<Self, Self::Error> {
        Ok(StatusConfig { enabled: x.enabled })
    }
}

#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct BlobEncryptionKey {
    data: [u8; 32],
}

impl Into<fidl::BlobEncryptionKey> for BlobEncryptionKey {
    fn into(self) -> fidl::BlobEncryptionKey {
        fidl::BlobEncryptionKey { data: self.data }
    }
}

impl TryFrom<Box<fidl::BlobEncryptionKey>> for BlobEncryptionKey {
    type Error = Error;
    fn try_from(x: Box<fidl::BlobEncryptionKey>) -> Result<Self, Self::Error> {
        Ok(BlobEncryptionKey { data: x.data })
    }
}

impl fmt::Debug for BlobEncryptionKey {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&hex::encode(self.data))
    }
}

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)))
    }
}
