wth 0.1.0

generate and set wallpaper from time-based hex colors
use anyhow::{Context, Result, bail};
use chrono::{Local, Timelike};
use image::{ImageBuffer, Rgb};
use std::{env, path::PathBuf, process::Command};

fn main() -> Result<()> {
    // wallpaper size (change if you want)
    let (w, h) = (1920u32, 1080u32);

    // output path: default /tmp/wth.png (override with WTH_OUT)
    let out_path = env::var("WTH_OUT")
        .map(PathBuf::from)
        .unwrap_or_else(|_| PathBuf::from("/tmp/wth.png"));

    // time -> hex: #HHMMSS
    let now = Local::now();
    // let hex = form0-t!(
    //     "#{:02X}{:02X}{:02X}",
    //     now.hour() as u8,
    //     now.minute() as u8,
    //     now.second() as u8
    // );

    let hex = "#034344";

    let rgb = hex_to_rgb(&hex)?;

    // generate image (solid fill)
    let img = ImageBuffer::from_pixel(w, h, Rgb(rgb));
    img.save(&out_path)
        .with_context(|| format!("failed to save image to {:?}", out_path))?;

    // set wallpaper
    // set_wallpaper(&out_path)?;

    println!(
        "time={} hex={} out={:?}",
        now.format("%H:%M:%S"),
        hex,
        out_path
    );
    Ok(())
}

fn hex_to_rgb(hex: &str) -> Result<[u8; 3]> {
    let s = hex.strip_prefix('#').unwrap_or(hex);
    if s.len() != 6 {
        bail!("hex color must be 6 chars like #A1B2C3 (got {hex})");
    }
    let r = u8::from_str_radix(&s[0..2], 16).context("bad R")?;
    let g = u8::from_str_radix(&s[2..4], 16).context("bad G")?;
    let b = u8::from_str_radix(&s[4..6], 16).context("bad B")?;
    Ok([r, g, b])
}

fn set_wallpaper(path: &PathBuf) -> Result<()> {
    // macOS
    if cfg!(target_os = "macos") {
        let script = format!(
            r#"tell application "System Events" to set picture of every desktop to POSIX file "{}""#,
            path.display()
        );
        let status = Command::new("osascript")
            .args(["-e", &script])
            .status()
            .context("failed to run osascript")?;

        if !status.success() {
            bail!("osascript failed");
        }
        return Ok(());
    }

    // Linux (GNOME/Ubuntu/etc via gsettings)
    if cfg!(target_os = "linux") {
        let uri = format!("file://{}", path.display());

        let status = Command::new("gsettings")
            .args(["set", "org.gnome.desktop.background", "picture-uri", &uri])
            .status();

        if let Ok(s) = status {
            if s.success() {
                // best-effort for GNOME dark mode
                let _ = Command::new("gsettings")
                    .args([
                        "set",
                        "org.gnome.desktop.background",
                        "picture-uri-dark",
                        &uri,
                    ])
                    .status();
                return Ok(());
            }
        }

        bail!("could not set wallpaper (gsettings missing or not GNOME-based)");
    }

    bail!("setting wallpaper not implemented for this OS");
}