//! Test infrastructure for comparing Rust BL implementations against XFOIL FORTRAN.
//!
//! This crate provides utilities for:
//! - Compiling and running FORTRAN test programs
//! - Loading JSON reference data
//! - Float comparison with tolerance

pub mod approx;
pub mod fortran_runner;
pub mod paths;
pub mod timing;

use serde::de::DeserializeOwned;
use std::fs;
use std::path::Path;

/// Load reference test data from a JSON file.
///
/// # Panics
/// Panics if the file cannot be read or parsed.
pub fn load_reference<T: DeserializeOwned>(path: impl AsRef<Path>) -> T {
    let path = path.as_ref();
    let contents = fs::read_to_string(path)
        .unwrap_or_else(|e| panic!("Failed to read reference file {}: {}", path.display(), e));
    serde_json::from_str(&contents)
        .unwrap_or_else(|e| panic!("Failed to parse JSON from {}: {}", path.display(), e))
}

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

    #[derive(Deserialize)]
    struct HkinTest {
        h: f64,
        msq: f64,
        hk: f64,
        hk_h: f64,
        hk_msq: f64,
    }

    #[derive(Deserialize)]
    struct HkinReference {
        hkin_tests: Vec<HkinTest>,
    }

    #[test]
    fn test_load_reference_works() {
        // Load the actual reference data generated by FORTRAN
        // Path is relative to workspace root where cargo test runs
        let path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
            .parent()
            .unwrap()
            .parent()
            .unwrap()
            .join("testdata/closures_reference.json");
        
        let reference: HkinReference = load_reference(&path);
        assert_eq!(reference.hkin_tests.len(), 400);
        
        // Verify first test case (H=1.0, M²=0.0 -> Hk=1.0)
        let first = &reference.hkin_tests[0];
        assert!((first.h - 1.0).abs() < 1e-4);
        assert!((first.msq - 0.0).abs() < 1e-4);
        assert!((first.hk - 1.0).abs() < 1e-4);
    }
}
