use image::imageops::FilterType;
use std::fs::remove_file;
use std::path::{Path, PathBuf};

use super::{ReadFileError, WriteFileError};

#[derive(Clone, Debug, PartialEq)]
pub struct Thumbnail {
    pub id: String,
    pub root: PathBuf,
}

impl Thumbnail {
    pub fn open(id: &str, root: &Path) -> Result<Thumbnail, WriteFileError> {
        /*
        let mut source_path = PathBuf::from(root);
        source_path.push(id);

        let self_ = Thumbnail {
            id: String::from(id),
            root: PathBuf::from(root),
        };

        let thumbnail_path = Thumbnail::thumbnail_path(id, root);
        if !thumbnail_path.exists() {
            let img = image::open(source_path)?;
            let tn = img.resize(640, 640, FilterType::Nearest);
            tn.save(thumbnail_path)?;
        }

        Ok(self_)
        */
        unimplemented!()
    }

    /*
    pub fn from_path(path: &Path) -> Result<Thumbnail, ReadFileError> {
        let id = path
            .file_name()
            .map(|s| String::from(s.to_string_lossy()))
            .ok_or(ReadFileError::NotAnImage(PathBuf::from(path)))?;

        let root = path
            .parent()
            .ok_or(ReadFileError::FileNotFound(PathBuf::from(path)))?;

        Thumbnail::open(&id, root)
    }
    */

    fn thumbnail_path(id: &str, root: &Path) -> PathBuf {
        let mut path = PathBuf::from(root);
        path.push(".thumbnails");
        path.push(id.clone());
        path
    }

    pub fn stream(&self) -> Result<std::fs::File, ReadFileError> {
        let thumbnail_path = Thumbnail::thumbnail_path(&self.id, &self.root);
        std::fs::File::open(thumbnail_path.clone()).map_err(|err| {
            if err.kind() == std::io::ErrorKind::NotFound {
                ReadFileError::FileNotFound
            } else {
                ReadFileError::from(err)
            }
        })
    }

    pub fn delete(&self) -> Result<(), WriteFileError> {
        let path = Thumbnail::thumbnail_path(&self.id, &self.root);
        remove_file(path).map_err(WriteFileError::from)
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::lib::utils::FileCleanup;

    #[test]
    fn it_creates_a_thumbnail_if_one_does_not_exist() {
        let _ = FileCleanup(PathBuf::from("fixtures/.thumbnails/rawr.png"));
        let _ =
            Thumbnail::open("rawr.png", Path::new("fixtures")).expect("thumbnail open must work");
        assert!(Path::new("fixtures/.thumbnails/rawr.png").is_file());
    }
}