//! 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, 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>,
    ) -> 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>>
    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>,
    ) -> 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>>
    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>,
    ) -> 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>>
    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>,
    ) -> 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>>
    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);
    }
}
