use std::fs;
use std::path::Path;

use serde_json::Value;

fn manifest_dir() -> &'static Path {
    Path::new(env!("CARGO_MANIFEST_DIR"))
}

fn read_json(path: impl AsRef<Path>) -> Value {
    let raw = fs::read_to_string(path.as_ref()).expect("read json file");
    serde_json::from_str(&raw).expect("valid json")
}

#[test]
fn csp_keeps_loopback_narrow() {
    let conf = read_json(manifest_dir().join("tauri.conf.json"));
    let csp = conf
        .pointer("/app/security/csp")
        .and_then(Value::as_str)
        .expect("csp string");
    let connect_src = csp
        .split(';')
        .map(str::trim)
        .find(|directive| directive.starts_with("connect-src "))
        .expect("connect-src directive");

    assert!(connect_src.contains("http://127.0.0.1:*"));
    assert!(connect_src.contains("ws://127.0.0.1:*"));
    assert!(!connect_src.contains("http://localhost:*"));
    assert!(!connect_src.contains("ws://localhost:*"));
}

#[test]
fn updater_is_signed_or_absent() {
    let conf = read_json(manifest_dir().join("tauri.conf.json"));
    if let Some(updater) = conf.pointer("/plugins/updater") {
        let pubkey = updater
            .get("pubkey")
            .and_then(Value::as_str)
            .unwrap_or_default();
        assert!(
            !pubkey.trim().is_empty(),
            "updater config must not ship with an empty pubkey"
        );
    }
}

#[test]
fn secondary_windows_do_not_get_high_risk_plugin_permissions() {
    let denied = [
        "dialog:",
        "autostart:",
        "global-shortcut:",
        "opener:",
        "updater:",
    ];
    let capability_dir = manifest_dir().join("capabilities");

    for entry in fs::read_dir(capability_dir).expect("capabilities dir") {
        let path = entry.expect("capability entry").path();
        if path.extension().and_then(|ext| ext.to_str()) != Some("json") {
            continue;
        }
        let capability = read_json(&path);
        let windows = capability
            .get("windows")
            .and_then(Value::as_array)
            .cloned()
            .unwrap_or_default();
        let applies_to_secondary = windows.iter().any(|window| {
            matches!(
                window.as_str(),
                Some("tasks-float" | "transcript-viewer" | "transcription-preview")
            )
        });
        if !applies_to_secondary {
            continue;
        }
        let permissions = capability
            .get("permissions")
            .and_then(Value::as_array)
            .cloned()
            .unwrap_or_default();
        for permission in permissions.iter().filter_map(Value::as_str) {
            assert!(
                !denied.iter().any(|prefix| permission.starts_with(prefix)),
                "{} grants high-risk permission {permission} to a secondary window",
                path.display()
            );
        }
    }
}
