//! Windows Firewall configuration

use anyhow::Result;
use std::process::Command;

pub fn add_firewall_rules() -> Result<()> {
    let daemon_path = crate::get_install_path().join("ostp-daemon.exe");
    let gui_path = crate::get_install_path().join("ostp-gui.exe");

    // Add inbound rule for daemon
    add_rule(
        "OSTP Daemon Inbound",
        &daemon_path.to_string_lossy(),
        "in",
    )?;

    // Add outbound rule for daemon
    add_rule(
        "OSTP Daemon Outbound",
        &daemon_path.to_string_lossy(),
        "out",
    )?;

    // Add inbound rule for GUI
    add_rule(
        "OSTP GUI Inbound",
        &gui_path.to_string_lossy(),
        "in",
    )?;

    // Add outbound rule for GUI
    add_rule(
        "OSTP GUI Outbound",
        &gui_path.to_string_lossy(),
        "out",
    )?;

    tracing::info!("Firewall rules added successfully");
    Ok(())
}

fn add_rule(name: &str, program: &str, direction: &str) -> Result<()> {
    let output = Command::new("netsh")
        .args([
            "advfirewall",
            "firewall",
            "add",
            "rule",
            &format!("name={}", name),
            &format!("dir={}", direction),
            "action=allow",
            &format!("program={}", program),
            "enable=yes",
        ])
        .output()?;

    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        anyhow::bail!("Failed to add firewall rule '{}': {}", name, stderr);
    }

    Ok(())
}
