kamft_desktop 0.0.4

Kamft desktop utilities including screenshot capture and WeChat Work integration
use super::{exe_path, APP_NAME};
use winreg::enums::{HKEY_CURRENT_USER, KEY_READ, KEY_WRITE, KEY_SET_VALUE};
use winreg::RegKey;

/// 检查是否已设置开机自启
pub fn is_enabled() -> bool {
    let exe = match exe_path() {
        Some(p) => p,
        None => return false,
    };

    let hkcu = RegKey::predef(HKEY_CURRENT_USER);

    let run_key = match hkcu.open_subkey_with_flags(
        r"Software\Microsoft\Windows\CurrentVersion\Run",
        KEY_READ,
    ) {
        Ok(k) => k,
        Err(_) => return false,
    };

    let stored: String = match run_key.get_value(APP_NAME) {
        Ok(v) => v,
        Err(_) => return false,
    };

    stored.trim_matches('"') == exe.trim_matches('"')
}

/// 启用开机自启(写入注册表)
pub fn enable() -> Result<(), String> {
    let exe = exe_path().ok_or("无法获取 exe 路径".to_string())?;
    let exe_quoted = format!("\"{}\"", exe);

    let hkcu = RegKey::predef(HKEY_CURRENT_USER);

    let (run_key, _) = hkcu
        .create_subkey_with_flags(
            r"Software\Microsoft\Windows\CurrentVersion\Run",
            KEY_WRITE,
        )
        .map_err(|e| format!("打开/创建注册表项失败: {e}"))?;

    run_key
        .set_value(APP_NAME, &exe_quoted)
        .map_err(|e| format!("写入注册表失败: {e}"))
}

/// 禁用开机自启(删除注册表项)
pub fn disable() -> Result<(), String> {
    let hkcu = RegKey::predef(HKEY_CURRENT_USER);

    let run_key = hkcu.open_subkey_with_flags(
        r"Software\Microsoft\Windows\CurrentVersion\Run",
        KEY_SET_VALUE,
    )
    .map_err(|e| format!("打开注册表项失败: {e}"))?;

    run_key
        .delete_value(APP_NAME)
        .map_err(|e| format!("删除注册表项失败: {e}"))
}

/// 切换开机自启状态,返回切换后的状态
pub fn toggle() -> Result<bool, String> {
    if is_enabled() {
        disable()?;
        Ok(false)
    } else {
        enable()?;
        Ok(true)
    }
}

// ── 计划任务(双重保障:登录时触发,支持延迟启动和失败重试) ──

const TASK_NAME: &str = "招财进宝小助手";

/// 检查计划任务是否已存在
pub fn is_scheduled_task_enabled() -> bool {
    let output = std::process::Command::new("schtasks")
        .args(["/query", "/tn", TASK_NAME])
        .output();
    output.map(|o| o.status.success()).unwrap_or(false)
}

/// 创建计划任务:用户登录时触发,延迟 30 秒启动,失败后重试
pub fn create_scheduled_task() -> Result<(), String> {
    let exe = exe_path().ok_or("无法获取 exe 路径".to_string())?;

    let output = std::process::Command::new("schtasks")
        .args([
            "/create",
            "/tn", TASK_NAME,
            "/tr", &exe,
            "/sc", "onlogon",              // 用户登录时触发
            "/delay", "0000:30",            // 延迟 30 秒(等桌面就绪)
            "/rl", "highest",               // 以最高权限运行
            "/f",                           // 强制覆盖同名任务
        ])
        .output()
        .map_err(|e| format!("执行 schtasks 失败: {e}"))?;

    if output.status.success() {
        Ok(())
    } else {
        let stderr = String::from_utf8_lossy(&output.stderr);
        Err(format!("创建计划任务失败: {stderr}"))
    }
}

/// 删除计划任务
pub fn delete_scheduled_task() -> Result<(), String> {
    let output = std::process::Command::new("schtasks")
        .args(["/delete", "/tn", TASK_NAME, "/f"])
        .output()
        .map_err(|e| format!("执行 schtasks 失败: {e}"))?;

    if output.status.success() {
        Ok(())
    } else {
        let stderr = String::from_utf8_lossy(&output.stderr);
        Err(format!("删除计划任务失败: {stderr}"))
    }
}

/// 同时启用 Run + 计划任务,返回详细结果
pub fn enable_all() -> Vec<(&'static str, Result<(), String>)> {
    vec![
        ("注册表Run", enable()),
        ("计划任务", create_scheduled_task()),
    ]
}

/// 同时禁用 Run + 计划任务
pub fn disable_all() -> Vec<(&'static str, Result<(), String>)> {
    vec![
        ("注册表Run", disable()),
        ("计划任务", delete_scheduled_task()),
    ]
}