//! Interfaces for interacting with different types of TUF repositories.

use hyper::{Url, Client};
use hyper::client::response::Response;
use hyper::header::{Headers, UserAgent};
use hyper::status::StatusCode;
use ring::digest::{self, SHA256, SHA512};
use std::collections::HashMap;
use std::fs::{self, File, DirBuilder};
use std::io::{Read, Write, Cursor};
use std::marker::PhantomData;
use std::path::PathBuf;
use tempfile::NamedTempFile;

use Result;
use crypto::{self, HashAlgorithm, HashValue};
use error::Error;
use metadata::{SignedMetadata, MetadataVersion, Unverified, Verified, Role, Metadata, TargetPath,
               TargetDescription, MetadataPath};
use interchange::DataInterchange;

/// Top-level trait that represents a TUF repository and contains all the ways it can be interacted
/// with.
pub trait Repository<D>
where
    D: DataInterchange,
{
    /// The type returned when reading a target.
    type TargetRead: Read;

    /// Initialize the repository.
    fn initialize(&mut self) -> Result<()>;

    /// Store signed metadata.
    fn store_metadata<M>(
        &mut self,
        role: &Role,
        meta_path: &MetadataPath,
        version: &MetadataVersion,
        metadata: &SignedMetadata<D, M, Verified>,
    ) -> Result<()>
    where
        M: Metadata;

    /// Fetch signed metadata.
    fn fetch_metadata<M>(
        &mut self,
        role: &Role,
        meta_path: &MetadataPath,
        version: &MetadataVersion,
        max_size: &Option<usize>,
        hash_data: Option<(&HashAlgorithm, &HashValue)>,
    ) -> Result<SignedMetadata<D, M, Unverified>>
    where
        M: Metadata;

    /// Store the given target.
    fn store_target<R>(
        &mut self,
        read: R,
        target_path: &TargetPath,
        target_description: &TargetDescription,
    ) -> Result<()>
    where
        R: Read;

    /// Fetch the given target.
    ///
    /// **WARNING**: The target will **NOT** yet be verified.
    fn fetch_target(&mut self, target_path: &TargetPath) -> Result<Self::TargetRead>;

    /// Perform a sanity check that `M`, `Role`, and `MetadataPath` all desrcribe the same entity.
    fn check<M>(role: &Role, meta_path: &MetadataPath) -> Result<()>
    where
        M: Metadata,
    {
        if role != &M::role() {
            return Err(Error::IllegalArgument(format!(
                "Attempted to store {} metadata as {}.",
                M::role(),
                role
            )));
        }

        if !role.fuzzy_matches_path(meta_path) {
            return Err(Error::IllegalArgument(
                format!("Role {} does not match path {:?}", role, meta_path),
            ));
        }

        Ok(())
    }

    /// Read the from given reader, optionally capped at `max_size` bytes, optionally requiring
    /// hashes to match.
    fn safe_read<R, W>(
        mut read: R,
        mut write: W,
        max_size: Option<i64>,
        hash_data: Option<(&HashAlgorithm, &HashValue)>,
    ) -> Result<()>
    where
        R: Read,
        W: Write,
    {
        let mut context = match hash_data {
            Some((&HashAlgorithm::Sha256, _)) => Some(digest::Context::new(&SHA256)),
            Some((&HashAlgorithm::Sha512, _)) => Some(digest::Context::new(&SHA512)),
            None => None,
        };

        let mut buf = [0; 1024];
        let mut bytes_left = max_size.unwrap_or(::std::i64::MAX);

        loop {
            match read.read(&mut buf) {
                Ok(read_bytes) => {
                    if read_bytes == 0 {
                        break;
                    }

                    bytes_left -= read_bytes as i64;
                    if bytes_left < 0 {
                        return Err(Error::VerificationFailure(
                            "Read exceeded the maximum allowed bytes.".into(),
                        ));
                    }

                    write.write_all(&buf[0..read_bytes])?;

                    match context {
                        Some(ref mut c) => c.update(&buf[0..read_bytes]),
                        None => (),
                    };
                }
                e @ Err(_) => e.map(|_| ())?,
            }
        }

        let generated_hash = context.map(|c| c.finish());

        match (generated_hash, hash_data) {
            (Some(generated_hash), Some((_, expected_hash)))
                if generated_hash.as_ref() != expected_hash.value() => {
                Err(Error::VerificationFailure(
                    "Generated hash did not match expected hash.".into(),
                ))
            }
            (Some(_), None) => {
                let msg = "Hash calculated when no expected hash supplied. \
                           This is a programming error. Please report this as a bug.";
                error!("{}", msg);
                Err(Error::Programming(msg.into()))
            }
            (None, Some(_)) => {
                let msg = "No hash calculated when expected hash supplied. \
                           This is a programming error. Please report this as a bug.";
                error!("{}", msg);
                Err(Error::Programming(msg.into()))
            }
            (Some(_), Some(_)) |
            (None, None) => Ok(()),
        }
    }
}

/// A repository contained on the local file system.
pub struct FileSystemRepository<D>
where
    D: DataInterchange,
{
    local_path: PathBuf,
    _interchange: PhantomData<D>,
}

impl<D> FileSystemRepository<D>
where
    D: DataInterchange,
{
    /// Create a new repository on the local file system.
    pub fn new(local_path: PathBuf) -> Self {
        FileSystemRepository {
            local_path: local_path,
            _interchange: PhantomData,
        }
    }
}

impl<D> Repository<D> for FileSystemRepository<D>
where
    D: DataInterchange,
{
    type TargetRead = File;

    fn initialize(&mut self) -> Result<()> {
        for p in &["metadata", "targets", "temp"] {
            DirBuilder::new().recursive(true).create(
                self.local_path.join(p),
            )?
        }

        Ok(())
    }

    fn store_metadata<M>(
        &mut self,
        role: &Role,
        meta_path: &MetadataPath,
        version: &MetadataVersion,
        metadata: &SignedMetadata<D, M, Verified>,
    ) -> Result<()>
    where
        M: Metadata,
    {
        Self::check::<M>(role, meta_path)?;

        let mut path = self.local_path.join("metadata");
        path.extend(meta_path.components::<D>(version));

        if path.exists() {
            debug!("Metadata path exists. Deleting: {:?}", path);
            fs::remove_file(&path)?
        }

        let mut file = File::create(&path)?;
        D::to_writer(&mut file, metadata)?;
        Ok(())

    }

    /// Fetch signed metadata.
    fn fetch_metadata<M>(
        &mut self,
        role: &Role,
        meta_path: &MetadataPath,
        version: &MetadataVersion,
        max_size: &Option<usize>,
        hash_data: Option<(&HashAlgorithm, &HashValue)>,
    ) -> Result<SignedMetadata<D, M, Unverified>>
    where
        M: Metadata,
    {
        Self::check::<M>(role, meta_path)?;

        let mut path = self.local_path.join("metadata");
        path.extend(meta_path.components::<D>(&version));

        let mut file = File::open(&path)?;
        let mut out = Vec::new();
        Self::safe_read(&mut file, &mut out, max_size.map(|x| x as i64), hash_data)?;

        Ok(D::from_reader(&*out)?)
    }

    fn store_target<R>(
        &mut self,
        read: R,
        target_path: &TargetPath,
        target_description: &TargetDescription,
    ) -> Result<()>
    where
        R: Read,
    {
        let mut temp_file = NamedTempFile::new_in(self.local_path.join("temp"))?;
        let hash_data = crypto::hash_preference(target_description.hashes())?;
        Self::safe_read(
            read,
            &mut temp_file,
            Some(target_description.length() as i64),
            Some(hash_data),
        )?;

        let mut path = self.local_path.clone().join("targets");
        path.extend(target_path.components());
        temp_file.persist(&path)?;

        Ok(())
    }

    fn fetch_target(&mut self, target_path: &TargetPath) -> Result<File> {
        let mut path = self.local_path.join("targets");
        path.extend(target_path.components());

        if !path.exists() {
            return Err(Error::NotFound);
        }

        Ok(File::open(&path)?)
    }
}


/// A repository accessible over HTTP.
pub struct HttpRepository<D>
where
    D: DataInterchange,
{
    url: Url,
    client: Client,
    user_agent: String,
    _interchange: PhantomData<D>,
}

impl<D> HttpRepository<D>
where
    D: DataInterchange,
{
    /// Create a new repository with the given `Url` and `Client`. Callers *should* include a
    /// custom User-Agent prefix to maintainers of TUF repositories keep track of which client
    /// versions exist in the field.
    pub fn new(url: Url, client: Client, user_agent_prefix: Option<String>) -> Self {
        let user_agent = match user_agent_prefix {
            Some(ua) => format!("{} (rust-tuf/{})", ua, env!("CARGO_PKG_VERSION")),
            None => format!("rust-tuf/{}", env!("CARGO_PKG_VERSION")),
        };

        HttpRepository {
            url: url,
            client: client,
            user_agent: user_agent,
            _interchange: PhantomData,
        }
    }

    fn get(&self, components: &[String]) -> Result<Response> {
        let mut headers = Headers::new();
        headers.set(UserAgent(self.user_agent.clone()));

        let mut url = self.url.clone();
        url.path_segments_mut()
            .map_err(|_| {
                Error::IllegalArgument(format!("URL was 'cannot-be-a-base': {:?}", self.url))
            })?
            .extend(components);

        let req = self.client.get(url.clone()).headers(headers);
        let resp = req.send()?;

        if !resp.status.is_success() {
            if resp.status == StatusCode::NotFound {
                Err(Error::NotFound)
            } else {
                Err(Error::Opaque(
                    format!("Error getting {:?}: {:?}", url, resp),
                ))
            }
        } else {
            Ok(resp)
        }
    }
}

impl<D> Repository<D> for HttpRepository<D>
where
    D: DataInterchange,
{
    type TargetRead = Response;

    fn initialize(&mut self) -> Result<()> {
        Ok(())
    }

    /// This always returns `Err` as storing over HTTP is not yet supported.
    fn store_metadata<M>(
        &mut self,
        _: &Role,
        _: &MetadataPath,
        _: &MetadataVersion,
        _: &SignedMetadata<D, M, Verified>,
    ) -> Result<()>
    where
        M: Metadata,
    {
        Err(Error::Opaque(
            "Http repo store metadata not implemented".to_string(),
        ))
    }

    fn fetch_metadata<M>(
        &mut self,
        role: &Role,
        meta_path: &MetadataPath,
        version: &MetadataVersion,
        max_size: &Option<usize>,
        hash_data: Option<(&HashAlgorithm, &HashValue)>,
    ) -> Result<SignedMetadata<D, M, Unverified>>
    where
        M: Metadata,
    {
        Self::check::<M>(role, meta_path)?;

        let mut resp = self.get(&meta_path.components::<D>(&version))?;
        let mut out = Vec::new();
        Self::safe_read(&mut resp, &mut out, max_size.map(|x| x as i64), hash_data)?;
        Ok(D::from_reader(&*out)?)
    }

    /// This always returns `Err` as storing over HTTP is not yet supported.
    fn store_target<R>(&mut self, _: R, _: &TargetPath, _: &TargetDescription) -> Result<()>
    where
        R: Read,
    {
        Err(Error::Opaque(
            "Http repo store  not implemented".to_string(),
        ))
    }

    fn fetch_target(&mut self, target_path: &TargetPath) -> Result<Self::TargetRead> {
        let resp = self.get(&target_path.components())?;
        Ok(resp)
    }
}


/// An ephemeral repository contained solely in memory.
pub struct EphemeralRepository<D>
where
    D: DataInterchange,
{
    metadata: HashMap<(MetadataPath, MetadataVersion), Vec<u8>>,
    targets: HashMap<TargetPath, Vec<u8>>,
    _interchange: PhantomData<D>,
}

impl<D> EphemeralRepository<D>
where
    D: DataInterchange,
{
    /// Create a new ephemercal repository.
    pub fn new() -> Self {
        EphemeralRepository {
            metadata: HashMap::new(),
            targets: HashMap::new(),
            _interchange: PhantomData,
        }
    }
}

impl<D> Repository<D> for EphemeralRepository<D>
where
    D: DataInterchange,
{
    type TargetRead = Cursor<Vec<u8>>;

    fn initialize(&mut self) -> Result<()> {
        Ok(())
    }

    fn store_metadata<M>(
        &mut self,
        role: &Role,
        meta_path: &MetadataPath,
        version: &MetadataVersion,
        metadata: &SignedMetadata<D, M, Verified>,
    ) -> Result<()>
    where
        M: Metadata,
    {
        Self::check::<M>(role, meta_path)?;
        let mut buf = Vec::new();
        D::to_writer(&mut buf, metadata)?;
        let _ = self.metadata.insert(
            (meta_path.clone(), version.clone()),
            buf,
        );
        Ok(())
    }

    fn fetch_metadata<M>(
        &mut self,
        role: &Role,
        meta_path: &MetadataPath,
        version: &MetadataVersion,
        max_size: &Option<usize>,
        hash_data: Option<(&HashAlgorithm, &HashValue)>,
    ) -> Result<SignedMetadata<D, M, Unverified>>
    where
        M: Metadata,
    {
        Self::check::<M>(role, meta_path)?;

        match self.metadata.get(&(meta_path.clone(), version.clone())) {
            Some(bytes) => {
                let mut buf = Vec::new();
                Self::safe_read(
                    bytes.as_slice(),
                    &mut buf,
                    max_size.map(|x| x as i64),
                    hash_data,
                )?;
                D::from_reader(&*buf)
            }
            None => Err(Error::NotFound),
        }
    }

    fn store_target<R>(
        &mut self,
        read: R,
        target_path: &TargetPath,
        target_description: &TargetDescription,
    ) -> Result<()>
    where
        R: Read,
    {
        let mut buf = Vec::new();
        let hash_data = crypto::hash_preference(target_description.hashes())?;
        Self::safe_read(
            read,
            &mut buf,
            Some(target_description.length() as i64),
            Some(hash_data),
        )?;
        let _ = self.targets.insert(target_path.clone(), buf);
        Ok(())
    }

    fn fetch_target(&mut self, target_path: &TargetPath) -> Result<Self::TargetRead> {
        match self.targets.get(target_path) {
            Some(bytes) => Ok(Cursor::new(bytes.clone())),
            None => Err(Error::NotFound),
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use tempdir::TempDir;
    use interchange::JsonDataInterchange;

    #[test]
    fn ephemeral_repo_targets() {
        let mut repo = EphemeralRepository::<JsonDataInterchange>::new();
        repo.initialize().expect("initialize repo");

        let data: &[u8] = b"like tears in the rain";
        let target_description =
            TargetDescription::from_reader(data).expect("generate target description");
        let path = TargetPath::new("batty".into()).expect("make target path");
        repo.store_target(data, &path, &target_description).expect(
            "store target",
        );

        let mut read = repo.fetch_target(&path).expect("fetch target");
        let mut buf = Vec::new();
        read.read_to_end(&mut buf).expect("read target");
        assert_eq!(buf.as_slice(), data);

        let bad_data: &[u8] = b"you're in a desert";
        assert!(
            repo.store_target(bad_data, &path, &target_description)
                .is_err()
        );

        let mut read = repo.fetch_target(&path).expect("fetch target");
        let mut buf = Vec::new();
        read.read_to_end(&mut buf).expect("read target");
        assert_eq!(buf.as_slice(), data);
    }

    #[test]
    fn file_system_repo_targets() {
        let temp_dir = TempDir::new("rust-tuf").expect("make temp dir");
        let mut repo =
            FileSystemRepository::<JsonDataInterchange>::new(temp_dir.path().to_path_buf());
        repo.initialize().expect("initialize repo");

        let data: &[u8] = b"like tears in the rain";
        let target_description =
            TargetDescription::from_reader(data).expect("generate target desert");
        let path = TargetPath::new("batty".into()).expect("make target path");
        repo.store_target(data, &path, &target_description).expect(
            "store target",
        );
        assert!(temp_dir.path().join("targets").join("batty").exists());

        let mut read = repo.fetch_target(&path).expect("fetch target");
        let mut buf = Vec::new();
        read.read_to_end(&mut buf).expect("read target");
        assert_eq!(buf.as_slice(), data);

        let bad_data: &[u8] = b"you're in a desert";
        assert!(
            repo.store_target(bad_data, &path, &target_description)
                .is_err()
        );

        let mut read = repo.fetch_target(&path).expect("fetch target");
        let mut buf = Vec::new();
        read.read_to_end(&mut buf).expect("read target");
        assert_eq!(buf.as_slice(), data);
    }
}
