//! Server-reachability / connectivity commands.
//!
//! TRACES: UR-043 | IR-027 | DR-055

use crate::connectivity::{ConnectivityMonitor, ConnectivityStatus};
use std::sync::Arc;
use tauri::State;

/// Wrapper for ConnectivityMonitor managed state
pub struct ConnectivityMonitorWrapper(pub Arc<tokio::sync::Mutex<ConnectivityMonitor>>);

/// Check if the server is currently reachable
#[tauri::command]
#[specta::specta]
pub async fn connectivity_check_server(
    state: State<'_, ConnectivityMonitorWrapper>,
) -> Result<bool, String> {
    let monitor = state.0.lock().await;
    Ok(monitor.check_reachability().await)
}

/// Set the server URL and trigger an immediate check
#[tauri::command]
#[specta::specta]
pub async fn connectivity_set_server_url(
    url: String,
    state: State<'_, ConnectivityMonitorWrapper>,
) -> Result<(), String> {
    let monitor = state.0.lock().await;
    monitor.set_server_url(url).await;
    Ok(())
}

/// Get the current connectivity status
#[tauri::command]
#[specta::specta]
pub async fn connectivity_get_status(
    state: State<'_, ConnectivityMonitorWrapper>,
) -> Result<ConnectivityStatus, String> {
    let monitor = state.0.lock().await;
    Ok(monitor.get_status().await)
}

/// Start monitoring connectivity with adaptive polling
#[tauri::command]
#[specta::specta]
pub async fn connectivity_start_monitoring(
    state: State<'_, ConnectivityMonitorWrapper>,
) -> Result<(), String> {
    let monitor = state.0.lock().await;
    monitor.start_monitoring().await;
    Ok(())
}

/// Stop monitoring connectivity
#[tauri::command]
#[specta::specta]
pub async fn connectivity_stop_monitoring(
    state: State<'_, ConnectivityMonitorWrapper>,
) -> Result<(), String> {
    let monitor = state.0.lock().await;
    monitor.stop_monitoring();
    Ok(())
}

/// Mark the server as reachable (called after successful API calls)
#[tauri::command]
#[specta::specta]
pub async fn connectivity_mark_reachable(
    state: State<'_, ConnectivityMonitorWrapper>,
) -> Result<(), String> {
    let monitor = state.0.lock().await;
    monitor.mark_reachable().await;
    Ok(())
}

/// Mark the server as unreachable (called after failed API calls)
#[tauri::command]
#[specta::specta]
pub async fn connectivity_mark_unreachable(
    error: Option<String>,
    state: State<'_, ConnectivityMonitorWrapper>,
) -> Result<(), String> {
    let monitor = state.0.lock().await;
    monitor.mark_unreachable(error).await;
    Ok(())
}

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

    #[test]
    fn test_connectivity_monitor_wrapper_structure() {
        // Test that wrapper can be created and holds Arc
        // We can't instantiate ConnectivityMonitor directly in tests
        // due to its dependencies, so we just test the wrapper type structure

        // This verifies the wrapper type exists and can hold Arc<Mutex>
        assert!(std::mem::size_of::<ConnectivityMonitorWrapper>() > 0);
    }
}
