//! Read-only Repository implementation backed by a web server.

use futures_io::AsyncRead;
use futures_util::future::{BoxFuture, FutureExt};
use futures_util::stream::TryStreamExt;
use http::{Response, StatusCode, Uri};
use hyper::body::Body;
use hyper::client::connect::Connect;
use hyper::Client;
use hyper::Request;
#[cfg(feature = "hyper_013")]
use hyper_013 as hyper;
#[cfg(feature = "hyper_014")]
use hyper_014 as hyper;
use percent_encoding::utf8_percent_encode;
use std::io;
use std::marker::PhantomData;
use url::Url;

use crate::error::Error;
use crate::interchange::DataInterchange;
use crate::metadata::{MetadataPath, MetadataVersion, TargetPath};
use crate::repository::RepositoryProvider;
use crate::util::SafeAsyncRead;
use crate::Result;

/// A builder to create a repository accessible over HTTP.
pub struct HttpRepositoryBuilder<C, D>
where
    C: Connect + Sync + 'static,
    D: DataInterchange,
{
    uri: Uri,
    client: Client<C>,
    user_agent: Option<String>,
    metadata_prefix: Option<Vec<String>>,
    targets_prefix: Option<Vec<String>>,
    min_bytes_per_second: u32,
    _interchange: PhantomData<D>,
}

impl<C, D> HttpRepositoryBuilder<C, D>
where
    C: Connect + Sync + 'static,
    D: DataInterchange,
{
    /// Create a new repository with the given `Url` and `Client`.
    pub fn new(url: Url, client: Client<C>) -> Self {
        HttpRepositoryBuilder {
            uri: url.to_string().parse::<Uri>().unwrap(), // This is dangerous, but will only exist for a short time as we migrate APIs.
            client,
            user_agent: None,
            metadata_prefix: None,
            targets_prefix: None,
            min_bytes_per_second: 4096,
            _interchange: PhantomData,
        }
    }

    /// Create a new repository with the given `Url` and `Client`.
    pub fn new_with_uri(uri: Uri, client: Client<C>) -> Self {
        HttpRepositoryBuilder {
            uri,
            client,
            user_agent: None,
            metadata_prefix: None,
            targets_prefix: None,
            min_bytes_per_second: 4096,
            _interchange: PhantomData,
        }
    }

    /// Set the User-Agent prefix.
    ///
    /// Callers *should* include a custom User-Agent prefix to help maintainers of TUF repositories
    /// keep track of which client versions exist in the field.
    ///
    pub fn user_agent<T: Into<String>>(mut self, user_agent: T) -> Self {
        self.user_agent = Some(user_agent.into());
        self
    }

    /// The argument `metadata_prefix` is used to provide an alternate path where metadata is
    /// stored on the repository. If `None`, this defaults to `/`. For example, if there is a TUF
    /// repository at `https://tuf.example.com/`, but all metadata is stored at `/meta/`, then
    /// passing the arg `Some("meta".into())` would cause `root.json` to be fetched from
    /// `https://tuf.example.com/meta/root.json`.
    pub fn metadata_prefix(mut self, metadata_prefix: Vec<String>) -> Self {
        self.metadata_prefix = Some(metadata_prefix);
        self
    }

    /// The argument `targets_prefix` is used to provide an alternate path where targets is
    /// stored on the repository. If `None`, this defaults to `/`. For example, if there is a TUF
    /// repository at `https://tuf.example.com/`, but all targets are stored at `/targets/`, then
    /// passing the arg `Some("targets".into())` would cause `hello-world` to be fetched from
    /// `https://tuf.example.com/targets/hello-world`.
    pub fn targets_prefix(mut self, targets_prefix: Vec<String>) -> Self {
        self.targets_prefix = Some(targets_prefix);
        self
    }

    /// Set the minimum bytes per second for a read to be considered good.
    pub fn min_bytes_per_second(mut self, min: u32) -> Self {
        self.min_bytes_per_second = min;
        self
    }

    /// Build a `HttpRepository`.
    pub fn build(self) -> HttpRepository<C, D> {
        let user_agent = match self.user_agent {
            Some(user_agent) => user_agent,
            None => "rust-tuf".into(),
        };

        HttpRepository {
            uri: self.uri,
            client: self.client,
            user_agent,
            metadata_prefix: self.metadata_prefix,
            targets_prefix: self.targets_prefix,
            min_bytes_per_second: self.min_bytes_per_second,
            _interchange: PhantomData,
        }
    }
}

/// A repository accessible over HTTP.
pub struct HttpRepository<C, D>
where
    C: Connect + Sync + 'static,
    D: DataInterchange,
{
    uri: Uri,
    client: Client<C>,
    user_agent: String,
    metadata_prefix: Option<Vec<String>>,
    targets_prefix: Option<Vec<String>>,
    min_bytes_per_second: u32,
    _interchange: PhantomData<D>,
}

// Configuration for urlencoding URI path elements.
// From https://url.spec.whatwg.org/#path-percent-encode-set
const URLENCODE_FRAGMENT: &percent_encoding::AsciiSet = &percent_encoding::CONTROLS
    .add(b' ')
    .add(b'"')
    .add(b'<')
    .add(b'>')
    .add(b'`');
const URLENCODE_PATH: &percent_encoding::AsciiSet =
    &URLENCODE_FRAGMENT.add(b'#').add(b'?').add(b'{').add(b'}');

fn extend_uri(uri: Uri, prefix: &Option<Vec<String>>, components: &[String]) -> Result<Uri> {
    let mut uri_parts = uri.into_parts();

    let (path, query) = match &uri_parts.path_and_query {
        Some(path_and_query) => (path_and_query.path(), path_and_query.query()),
        None => ("", None),
    };

    let mut modified_path = path.to_owned();
    if modified_path.ends_with('/') {
        modified_path.pop();
    }

    let mut path_split = modified_path
        .split('/')
        .map(String::from)
        .collect::<Vec<_>>();
    let mut new_path_elements: Vec<&str> = vec![];

    if let Some(ref prefix) = prefix {
        new_path_elements.extend(prefix.iter().map(String::as_str));
    }
    new_path_elements.extend(components.iter().map(String::as_str));

    // Urlencode new items to match behavior of PathSegmentsMut.extend from
    // https://docs.rs/url/2.1.0/url/struct.PathSegmentsMut.html
    let encoded_new_path_elements = new_path_elements
        .into_iter()
        .map(|path_segment| utf8_percent_encode(path_segment, URLENCODE_PATH).collect());
    path_split.extend(encoded_new_path_elements);
    let constructed_path = path_split.join("/");

    uri_parts.path_and_query =
        match query {
            Some(query) => Some(format!("{}?{}", constructed_path, query).parse().map_err(
                |_| {
                    Error::IllegalArgument(format!(
                        "Invalid path and query: {:?}, {:?}",
                        constructed_path, query
                    ))
                },
            )?),
            None => Some(constructed_path.parse().map_err(|_| {
                Error::IllegalArgument(format!("Invalid URI path: {:?}", constructed_path))
            })?),
        };

    Uri::from_parts(uri_parts).map_err(|_| {
        Error::IllegalArgument(format!(
            "Invalid URI parts: {:?}, {:?}, {:?}",
            constructed_path, prefix, components
        ))
    })
}

impl<C, D> HttpRepository<C, D>
where
    C: Connect + Clone + Send + Sync + 'static,
    D: DataInterchange,
{
    async fn get<'a>(
        &'a self,
        prefix: &'a Option<Vec<String>>,
        components: &'a [String],
    ) -> Result<Response<Body>> {
        let base_uri = self.uri.clone();
        let uri = extend_uri(base_uri, prefix, components)?;

        let req = Request::builder()
            .uri(&uri)
            .header("User-Agent", &*self.user_agent)
            .body(Body::default())?;

        let resp = self.client.request(req).await?;
        let status = resp.status();

        if status == StatusCode::OK {
            Ok(resp)
        } else if status == StatusCode::NOT_FOUND {
            Err(Error::NotFound)
        } else {
            Err(Error::BadHttpStatus {
                code: status,
                uri: uri.to_string(),
            })
        }
    }
}

impl<C, D> RepositoryProvider<D> for HttpRepository<C, D>
where
    C: Connect + Clone + Send + Sync + 'static,
    D: DataInterchange + Send + Sync,
{
    fn fetch_metadata<'a>(
        &'a self,
        meta_path: &MetadataPath,
        version: MetadataVersion,
    ) -> BoxFuture<'a, Result<Box<dyn AsyncRead + Send + Unpin + 'a>>> {
        let components = meta_path.components::<D>(version);
        async move {
            let resp = self.get(&self.metadata_prefix, &components).await?;

            // TODO(#278) check content length if known and fail early if the payload is too large.

            let reader = resp
                .into_body()
                .map_err(|err| io::Error::new(io::ErrorKind::Other, err))
                .into_async_read()
                .enforce_minimum_bitrate(self.min_bytes_per_second);

            let reader: Box<dyn AsyncRead + Send + Unpin> = Box::new(reader);
            Ok(reader)
        }
        .boxed()
    }

    fn fetch_target<'a>(
        &'a self,
        target_path: &TargetPath,
    ) -> BoxFuture<'a, Result<Box<dyn AsyncRead + Send + Unpin + 'a>>> {
        let components = target_path.components();

        async move {
            // TODO(#278) check content length if known and fail early if the payload is too large.
            let resp = self.get(&self.targets_prefix, &components).await?;

            let reader = resp
                .into_body()
                .map_err(|err| io::Error::new(io::ErrorKind::Other, err))
                .into_async_read()
                .enforce_minimum_bitrate(self.min_bytes_per_second);

            Ok(Box::new(reader) as Box<dyn AsyncRead + Send + Unpin>)
        }
        .boxed()
    }
}

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

    // Old behavior of the `HttpRepository::get` extension
    // functionality
    fn http_repository_extend_using_url(
        base_url: Url,
        prefix: &Option<Vec<String>>,
        components: &[String],
    ) -> url::Url {
        let mut url = base_url;
        {
            let mut segments = url.path_segments_mut().unwrap();
            if let Some(ref prefix) = prefix {
                segments.extend(prefix);
            }
            segments.extend(components);
        }
        url
    }

    #[test]
    fn http_repository_uri_construction() {
        let base_uri = "http://example.com/one";

        let prefix = Some(vec![String::from("prefix")]);
        let components = [
            String::from("components_one"),
            String::from("components_two"),
        ];

        let uri = base_uri.parse::<Uri>().unwrap();
        let extended_uri = extend_uri(uri, &prefix, &components).unwrap();

        let url =
            http_repository_extend_using_url(Url::parse(base_uri).unwrap(), &prefix, &components);

        assert_eq!(url.to_string(), extended_uri.to_string());
        assert_eq!(
            extended_uri.to_string(),
            "http://example.com/one/prefix/components_one/components_two"
        );
    }

    #[test]
    fn http_repository_uri_construction_encoded() {
        let base_uri = "http://example.com/one";

        let prefix = Some(vec![String::from("prefix")]);
        let components = [String::from("chars to encode#?")];
        let uri = base_uri.parse::<Uri>().unwrap();
        let extended_uri = extend_uri(uri, &prefix, &components)
            .expect("correctly generated a URI with a zone id");

        let url =
            http_repository_extend_using_url(Url::parse(base_uri).unwrap(), &prefix, &components);

        assert_eq!(url.to_string(), extended_uri.to_string());
        assert_eq!(
            extended_uri.to_string(),
            "http://example.com/one/prefix/chars%20to%20encode%23%3F"
        );
    }

    #[test]
    fn http_repository_uri_construction_no_components() {
        let base_uri = "http://example.com/one";

        let prefix = Some(vec![String::from("prefix")]);
        let components = [];

        let uri = base_uri.parse::<Uri>().unwrap();
        let extended_uri = extend_uri(uri, &prefix, &components).unwrap();

        let url =
            http_repository_extend_using_url(Url::parse(base_uri).unwrap(), &prefix, &components);

        assert_eq!(url.to_string(), extended_uri.to_string());
        assert_eq!(extended_uri.to_string(), "http://example.com/one/prefix");
    }

    #[test]
    fn http_repository_uri_construction_no_prefix() {
        let base_uri = "http://example.com/one";

        let prefix = None;
        let components = [
            String::from("components_one"),
            String::from("components_two"),
        ];

        let uri = base_uri.parse::<Uri>().unwrap();
        let extended_uri = extend_uri(uri, &prefix, &components).unwrap();

        let url =
            http_repository_extend_using_url(Url::parse(base_uri).unwrap(), &prefix, &components);

        assert_eq!(url.to_string(), extended_uri.to_string());
        assert_eq!(
            extended_uri.to_string(),
            "http://example.com/one/components_one/components_two"
        );
    }

    #[test]
    fn http_repository_uri_construction_with_query() {
        let base_uri = "http://example.com/one?test=1";

        let prefix = None;
        let components = [
            String::from("components_one"),
            String::from("components_two"),
        ];

        let uri = base_uri.parse::<Uri>().unwrap();
        let extended_uri = extend_uri(uri, &prefix, &components).unwrap();

        let url =
            http_repository_extend_using_url(Url::parse(base_uri).unwrap(), &prefix, &components);

        assert_eq!(url.to_string(), extended_uri.to_string());
        assert_eq!(
            extended_uri.to_string(),
            "http://example.com/one/components_one/components_two?test=1"
        );
    }

    #[test]
    fn http_repository_uri_construction_ipv6_zoneid() {
        let base_uri = "http://[aaaa::aaaa:aaaa:aaaa:1234%252]:80";

        let prefix = Some(vec![String::from("prefix")]);
        let components = [
            String::from("componenents_one"),
            String::from("components_two"),
        ];
        let uri = base_uri.parse::<Uri>().unwrap();
        let extended_uri = extend_uri(uri, &prefix, &components)
            .expect("correctly generated a URI with a zone id");
        assert_eq!(
            extended_uri.to_string(),
            "http://[aaaa::aaaa:aaaa:aaaa:1234%252]:80/prefix/componenents_one/components_two"
        );
    }
}
