use crate::util::dimensions::DimensionsExtractor;
use std::fs::File;
use std::io;
use crate::util::Dimensions;
use matroska::MatroskaError;
use std::path::Path;

pub struct MkvDimensionsExtractor;

impl DimensionsExtractor for MkvDimensionsExtractor {
    fn supports_ext(&self, ext_lowercase: &str) -> bool {
        "mkv" == ext_lowercase
    }

    fn try_read_dimensions(&self, path: &Path) -> io::Result<Option<Dimensions>> {
        let fd = File::open(path)?;
        let matroska = matroska::Matroska::open(fd).map_err(|err| {
            match err {
                MatroskaError::Io(io) => { io }
                MatroskaError::UTF8(utf8) => { io::Error::new(io::ErrorKind::InvalidData, utf8) }
                e => io::Error::new(io::ErrorKind::InvalidData, e)
            }
        })?;
        Ok(matroska.tracks.iter()
            .find(|&track| track.tracktype == matroska::Tracktype::Video)
            .and_then(|ref track| {
                if let matroska::Settings::Video(settings) = &track.settings {
                    Some(Dimensions {
                        width: settings.pixel_width as usize,
                        height: settings.pixel_height as usize,
                    })
                } else { None }
            }))
    }
}


#[cfg(test)]
mod test {
    use crate::util::dimensions::{Dimensions, test::test_successful};
    use super::MkvDimensionsExtractor;
    use std::error::Error;

    #[test]
    fn test_success() -> Result<(), Box<dyn Error>> {
        test_successful(MkvDimensionsExtractor, "video/rust-logo-blk.mkv", Some(Dimensions { width: 144, height: 144 }))
    }
}



