// TODO: remove tests of CompressionFormat::try_from since that's no longer used anywhere

#[cfg(test)]
mod cli {

    use crate::cli::clap_app;
    use crate::cli::Command;
    use crate::cli::CommandKind::*;
    use crate::error::OuchResult;
    use crate::extension::CompressionFormat::*;
    use crate::extension::Extension;
    use crate::file::File;
    use std::convert::TryFrom;

    #[test]
    fn decompress_files_into_folder() -> OuchResult<()> {
        let matches = clap_app().get_matches_from(vec!["ouch", "-i", "file.zip", "-o", "folder/"]);
        let command_from_matches = Command::try_from(matches)?;

        assert_eq!(
            command_from_matches,
            Command {
                kind: Decompression(vec![
                    File { 
                        path: "file.zip".into(),
                        contents_in_memory: None,
                        extension: Some(Extension::from(Zip))
                    }
                ]),
                output: Some(File {
                    path: "folder".into(),
                    contents_in_memory: None,
                    extension: None
                }),
            }
        );

        Ok(())
    }

    #[test]
    fn decompress_files() -> OuchResult<()> {
        let matches = clap_app().get_matches_from(vec!["ouch", "-i", "file.zip", "file.tar"]);
        let command_from_matches = Command::try_from(matches)?;

        assert_eq!(
            command_from_matches,
            Command {
                kind: Decompression(vec![
                    File { 
                        path: "file.zip".into(),
                        contents_in_memory: None,
                        extension: Some(Extension::from(Zip))
                    },
                    File { 
                        path: "file.tar".into(),
                        contents_in_memory: None,
                        extension: Some(Extension::from(Tar))
                    }
                ],),
                output: None,
            }
        );

        Ok(())
    }

    #[test]
    fn compress_files() -> OuchResult<()> {
        let matches = clap_app().get_matches_from(vec![
            "ouch",
            "-i",
            "file",
            "file2.jpeg",
            "file3.ok",
            "-o",
            "file.tar",
        ]);
        let command_from_matches = Command::try_from(matches)?;

        assert_eq!(
            command_from_matches,
            Command {
                kind: Compression(vec![
                    "file".into(),
                    "file2.jpeg".into(),
                    "file3.ok".into()
                ]),
                output: Some(
                    File {
                        path: "file.tar".into(),
                        contents_in_memory: None,
                        extension: Some(Extension::from(Tar))
                    }
                ),
            }
        );

        Ok(())
    }
}

#[cfg(test)]
mod cli_errors {

    use std::convert::TryFrom;

    use crate::cli::clap_app;
    use crate::cli::Command;
    use crate::error::Error;
    use crate::error::OuchResult;

    #[test]
    fn compress_files() -> OuchResult<()> {
        let matches =
            clap_app().get_matches_from(vec!["ouch", "-i", "a_file", "file2.jpeg", "file3.ok"]);
        let res = Command::try_from(matches);

        assert_eq!(
            res,
            Err(Error::InputsMustHaveBeenDecompressible("a_file".into()))
        );

        Ok(())
    }
}

#[cfg(test)]
mod extension_extraction {
    use crate::{error::OuchResult, extension::Extension}    ;
    use crate::extension::CompressionFormat;
    use std::{convert::TryFrom, path::PathBuf, str::FromStr};

    #[test]
    fn zip() -> OuchResult<()> {
        let path = PathBuf::from_str("filename.tar.zip").unwrap();
        assert_eq!(
            CompressionFormat::try_from(&path)?,
            CompressionFormat::Zip
        );

        Ok(())
    }
    
    #[test]
    fn tar_gz() -> OuchResult<()> {
        let extension = Extension::new("folder.tar.gz")?;

        assert_eq!(
            extension,
            Extension {
                first_ext: Some(CompressionFormat::Tar),
                second_ext: CompressionFormat::Gzip
            }
        );

        Ok(())
    }

    #[test]
    fn tar() -> OuchResult<()> {
        let path = PathBuf::from_str("pictures.tar").unwrap();
        assert_eq!(
            CompressionFormat::try_from(&path)?,
            CompressionFormat::Tar
        );

        Ok(())
    }

    #[test]
    fn gz() -> OuchResult<()> {
        let path = PathBuf::from_str("passwords.tar.gz").unwrap();
        assert_eq!(
            CompressionFormat::try_from(&path)?,
            CompressionFormat::Gzip
        );

        Ok(())
    }

    #[test]
    fn lzma() -> OuchResult<()> {
        let path = PathBuf::from_str("mygame.tar.lzma").unwrap();
        assert_eq!(
            CompressionFormat::try_from(&path)?,
            CompressionFormat::Lzma
        );

        Ok(())
    }

    #[test]
    fn bz() -> OuchResult<()> {
        let path = PathBuf::from_str("songs.tar.bz").unwrap();
        assert_eq!(
            CompressionFormat::try_from(&path)?,
            CompressionFormat::Bzip
        );

        Ok(())
    }
}

// #[cfg(test)]
// mod evaluator {
//     use crate::extension::Extension;
//     use crate::error::OuchResult;
//     use crate::file::File;
//     use crate::evaluator::Evaluator;
//     use crate::decompressors::{Decompressor, TarDecompressor, GzipDecompressor};

//     #[test]
//     fn test() -> OuchResult<()> {
//         let extension = Extension::new("folder.tar.gz")?;

//         let file = File {
//             path: "folder.tar.gz".into(),
//             contents_in_memory: None,
//             extension: Some(extension),
//         };

//         let (fst, snd) = Evaluator::get_decompressor(&file)?;

//         let fst = fst.unwrap();

//         assert_eq!(
//             fst,
//             Some(Box::new(TarDecompressor::{})
//         );

//         Ok(())
//     }
// }