#![warn(missing_docs)]
use std::io::Cursor;
use std::path::Path;
use anyhow::anyhow;
use id3::TagLike;
use image::DynamicImage;
pub fn embed_image(music_filename: &Path, image_filename: &Path) -> anyhow::Result<()> {
    let image = image::open(&image_filename)
        .map_err(|e| anyhow!("Error reading image {:?}: {}", image_filename, e))?;
    embed_image_from_memory(music_filename, &image)
}
pub fn embed_image_from_memory(
    music_filename: &Path,
    image: &image::DynamicImage,
) -> anyhow::Result<()> {
    let mut tag = read_tag(music_filename)?;
    let mut encoded_image_bytes = Cursor::new(Vec::new());
        image
        .write_to(&mut encoded_image_bytes, image::ImageOutputFormat::Jpeg(90))
        .unwrap();
    tag.add_frame(id3::frame::Picture {
        mime_type: "image/jpeg".to_string(),
        picture_type: id3::frame::PictureType::CoverFront,
        description: String::new(),
        data: encoded_image_bytes.into_inner(),
    });
    tag.write_to_path(music_filename, id3::Version::Id3v23)
        .map_err(|e| {
            anyhow!(
                "Error writing image to music file {:?}: {}",
                music_filename,
                e
            )
        })?;
    Ok(())
}
pub fn extract_first_image(music_filename: &Path, image_filename: &Path) -> anyhow::Result<()> {
    extract_first_image_as_img(music_filename)?
        .save(&image_filename)
        .map_err(|e| anyhow!("Couldn't write image file {:?}: {}", image_filename, e))
}
pub fn extract_first_image_as_img(music_filename: &Path) -> anyhow::Result<DynamicImage> {
    let tag = read_tag(music_filename)?;
    let first_picture = tag.pictures().next();
    if let Some(p) = first_picture {
        image::load_from_memory(&p.data).map_err(|e| anyhow!("Couldn't load image: {}", e))
    } else {
        Err(anyhow!("No image found in music file"))
    }
}
pub fn remove_images(music_filename: &Path) -> anyhow::Result<()> {
    let mut tag = read_tag(music_filename)?;
    tag.remove("APIC");
    tag.write_to_path(music_filename, id3::Version::Id3v23)
        .map_err(|e| anyhow!("Error updating music file {:?}: {}", music_filename, e))?;
    Ok(())
}
fn read_tag(path: &Path) -> anyhow::Result<id3::Tag> {
    id3::Tag::read_from_path(&path).or_else(|e| {
        eprintln!(
            "Warning: file metadata is corrupted, trying to read partial tag: {}",
            path.display()
        );
        e.partial_tag
            .clone()
            .ok_or_else(|| anyhow!("Error reading music file {:?}: {}", path, e))
    })
}