#![warn(
    clippy::pedantic,
    // nursery lints:
    clippy::use_self,
    clippy::or_fun_call,
    clippy::redundant_clone,
    clippy::equatable_if_let,
    clippy::needless_collect,
    // restriction lints:
    clippy::redundant_type_annotations,
    clippy::semicolon_inside_block,
    clippy::allow_attributes
)]
// when used, scope is restricted (use statement inside functions)
#![allow(clippy::enum_glob_use)]

pub mod cli;
pub mod cursors;
pub mod formats;
pub mod fs_utils;
pub mod themes;

/// Helper for compile-time paths for tests.
#[cfg(test)]
macro_rules! from_root {
    ($path:literal) => {
        concat!(env!("CARGO_MANIFEST_DIR"), $path)
    };
}

#[cfg(test)]
use from_root;

use crate::{
    cli::{Args, ParsedArgs},
    cursors::generic_cursor::GenericCursor,
    themes::theme::CursorTheme,
};

use anyhow::{Context, Result, anyhow};
use clap::Parser;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};

fn main() -> Result<()> {
    let raw_args = Args::parse();
    let args = ParsedArgs::from_args(raw_args)?;

    args.cursor_theme_dirs.par_iter().try_for_each(|d| {
        let mut theme = CursorTheme::from_theme_dir(d)
            .with_context(|| format!("while reading dir={} as theme", d.display()))?;

        for &sf in &args.scale_to {
            theme.add_scale(sf, args.get_algorithm(sf))?;
        }

        theme.save_as_x11_theme(&args.out)
    })?;

    args.cursor_files.par_iter().try_for_each(|f| {
        let mut cursor = GenericCursor::from_path(f)
            .with_context(|| format!("while reading f={} as cursor", f.display()))?;

        let filename = args.out.join(
            f.file_stem()
                .ok_or_else(|| anyhow!("no file stem for cursor_file={}", f.display()))?,
        );

        for &sf in &args.scale_to {
            cursor.add_scale(sf, args.get_algorithm(sf))?;
        }

        cursor.save_as_xcursor(filename)
    })?;

    Ok(())
}
