//! SAS Client - Named pipe client for communicating with GuruConnect SAS Service
//!
//! The SAS Service runs as SYSTEM and handles Ctrl+Alt+Del requests.
//! This client sends commands to the service via named pipe.

use std::fs::OpenOptions;
use std::io::{Read, Write};

use anyhow::{Context, Result};
use tracing::{debug, error, info, warn};

const PIPE_NAME: &str = r"\\.\pipe\guruconnect-sas";

/// Request Ctrl+Alt+Del (Secure Attention Sequence) via the SAS service
pub fn request_sas() -> Result<()> {
    info!("Requesting SAS via service pipe...");

    // Try to connect to the pipe
    let mut pipe = match OpenOptions::new().read(true).write(true).open(PIPE_NAME) {
        Ok(p) => p,
        Err(e) => {
            warn!("Failed to connect to SAS service pipe: {}", e);
            return Err(anyhow::anyhow!(
                "SAS service not available. Install with: guruconnect-sas-service install"
            ));
        }
    };

    debug!("Connected to SAS service pipe");

    // Send the command
    pipe.write_all(b"sas\n")
        .context("Failed to send command to SAS service")?;

    // Read the response
    let mut response = [0u8; 64];
    let n = pipe
        .read(&mut response)
        .context("Failed to read response from SAS service")?;

    let response_str = String::from_utf8_lossy(&response[..n]);
    let response_str = response_str.trim();

    debug!("SAS service response: {}", response_str);

    match response_str {
        "ok" => {
            info!("SAS request successful");
            Ok(())
        }
        "error" => {
            error!("SAS service reported an error");
            Err(anyhow::anyhow!("SAS service failed to send Ctrl+Alt+Del"))
        }
        _ => {
            error!("Unexpected response from SAS service: {}", response_str);
            Err(anyhow::anyhow!(
                "Unexpected SAS service response: {}",
                response_str
            ))
        }
    }
}

/// Check if the SAS service is available
// Used by the test module and the (not-yet-wired) SAS status API.
#[allow(dead_code)]
pub fn is_service_available() -> bool {
    // Try to open the pipe
    if let Ok(mut pipe) = OpenOptions::new().read(true).write(true).open(PIPE_NAME) {
        // Send a ping command
        if pipe.write_all(b"ping\n").is_ok() {
            let mut response = [0u8; 64];
            if let Ok(n) = pipe.read(&mut response) {
                let response_str = String::from_utf8_lossy(&response[..n]);
                return response_str.trim() == "pong";
            }
        }
    }
    false
}

/// Get information about SAS service status
#[allow(dead_code)]
pub fn get_service_status() -> String {
    if is_service_available() {
        "SAS service is running and responding".to_string()
    } else {
        "SAS service is not available".to_string()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_service_check() {
        // This test just checks the function runs without panicking
        let available = is_service_available();
        println!("SAS service available: {}", available);
    }
}
