//! Tests for single simulation execution.

use entropyk_cli::error::ExitCode;
use entropyk_cli::run::{SimulationResult, SimulationStatus};
use tempfile::tempdir;

#[test]
fn test_simulation_result_serialization() {
    let result = SimulationResult {
        input: "test.json".to_string(),
        status: SimulationStatus::Converged,
        convergence: Some(entropyk_cli::run::ConvergenceInfo {
            final_residual: 1e-8,
            tolerance: 1e-6,
        }),
        iterations: Some(25),
        state: Some(vec![entropyk_cli::run::StateEntry {
            edge: 0,
            pressure_bar: 10.0,
            enthalpy_kj_kg: 400.0,
        }]),
        error: None,
        elapsed_ms: 50,
    };

    let json = serde_json::to_string_pretty(&result).unwrap();
    assert!(json.contains("\"status\": \"converged\""));
    assert!(json.contains("\"iterations\": 25"));
    assert!(json.contains("\"pressure_bar\": 10.0"));
}

#[test]
fn test_simulation_status_values() {
    assert_eq!(SimulationStatus::Converged, SimulationStatus::Converged);
    assert_ne!(SimulationStatus::Converged, SimulationStatus::Error);

    let status = SimulationStatus::NonConverged;
    let json = serde_json::to_string(&status).unwrap();
    assert_eq!(json, "\"non_converged\"");
}

#[test]
fn test_exit_codes() {
    assert_eq!(ExitCode::Success as i32, 0);
    assert_eq!(ExitCode::SimulationError as i32, 1);
    assert_eq!(ExitCode::ConfigError as i32, 2);
    assert_eq!(ExitCode::IoError as i32, 3);
}

#[test]
fn test_error_result_serialization() {
    let result = SimulationResult {
        input: "invalid.json".to_string(),
        status: SimulationStatus::Error,
        convergence: None,
        iterations: None,
        state: None,
        error: Some("Configuration error".to_string()),
        elapsed_ms: 0,
    };

    let json = serde_json::to_string(&result).unwrap();
    assert!(json.contains("Configuration error"));
}

#[test]
fn test_create_minimal_config_file() {
    let dir = tempdir().unwrap();
    let config_path = dir.path().join("minimal.json");

    let json = r#"{ "fluid": "R134a" }"#;
    std::fs::write(&config_path, json).unwrap();

    assert!(config_path.exists());
    let content = std::fs::read_to_string(&config_path).unwrap();
    assert!(content.contains("R134a"));
}
