headroom 2.0.0

Audio loudness analyzer and gain adjustment tool for mastering workflows
use console::style;
use std::time::Duration;
use update_informer::{registry, Check};

const PKG_NAME: &str = "M-Igashi/headroom";
const CHECK_INTERVAL: Duration = Duration::from_secs(60 * 60 * 24);

pub fn check_and_notify() {
    if std::env::var_os("HEADROOM_NO_UPDATE_CHECK").is_some() {
        return;
    }

    let current = env!("CARGO_PKG_VERSION");
    let informer = update_informer::new(registry::GitHub, PKG_NAME, current).interval(CHECK_INTERVAL);

    let Ok(Some(new_version)) = informer.check_version() else {
        return;
    };

    let new_str = new_version.to_string();
    let stripped = new_str.strip_prefix('v').unwrap_or(&new_str);

    println!(
        "{} Update available: {}{}",
        style("").yellow().bold(),
        style(format!("v{}", current)).dim(),
        style(format!("v{}", stripped)).green().bold()
    );

    for line in update_commands() {
        println!("   {}", style(line).dim());
    }
    println!();
}

fn update_commands() -> Vec<String> {
    if let Some(method) = detect_install_method() {
        return vec![method.command().to_string()];
    }

    let mut lines = Vec::new();
    if cfg!(target_os = "macos") {
        lines.push(InstallMethod::Homebrew.command().to_string());
        lines.push(InstallMethod::Cargo.command().to_string());
    } else if cfg!(target_os = "windows") {
        lines.push(InstallMethod::Winget.command().to_string());
        lines.push(InstallMethod::Cargo.command().to_string());
    } else {
        lines.push(InstallMethod::Cargo.command().to_string());
    }
    lines
}

#[derive(Clone, Copy)]
enum InstallMethod {
    Homebrew,
    Winget,
    Cargo,
}

impl InstallMethod {
    fn command(self) -> &'static str {
        match self {
            InstallMethod::Homebrew => "brew upgrade headroom",
            InstallMethod::Winget => "winget upgrade M-Igashi.headroom",
            InstallMethod::Cargo => "cargo install headroom",
        }
    }
}

fn detect_install_method() -> Option<InstallMethod> {
    let exe = std::env::current_exe().ok()?;
    let path = exe.to_string_lossy().to_lowercase();

    if path.contains("/homebrew/") || path.contains("/cellar/") || path.contains("/linuxbrew/") {
        Some(InstallMethod::Homebrew)
    } else if path.contains("\\winget\\") || path.contains("/winget/") {
        Some(InstallMethod::Winget)
    } else if path.contains("/.cargo/") || path.contains("\\.cargo\\") {
        Some(InstallMethod::Cargo)
    } else {
        None
    }
}