use super::*;
use crate::test_support::write_temp_json;

#[test]
fn loads_input_document() {
    let text = serde_json::to_string(&RuntimeStateInputDocument {
        format_version: STATE_INPUT_DOCUMENT_FORMAT_VERSION,
        input_id: "input-smoke".to_string(),
        source: RuntimeStateInputSource {
            description: Some("test input".to_string()),
            source_binary: None,
        },
        state: state(),
    })
    .expect("input document should serialize");

    let input =
        load_runtime_state_input_from_str(&text, "fallback").expect("input document should load");
    assert_eq!(input.input_id, "input-smoke");
    assert_eq!(input.description.as_deref(), Some("test input"));
}

#[test]
fn loads_bare_runtime_state() {
    let text = serde_json::to_string(&state()).expect("state should serialize");
    let input = load_runtime_state_input_from_str(&text, "fallback").expect("state should load");
    assert_eq!(input.input_id, "fallback");
    assert!(input.description.is_none());
}

#[test]
fn validates_and_roundtrips_save_slice_document() {
    let document = RuntimeSaveSliceDocument {
        format_version: SAVE_SLICE_DOCUMENT_FORMAT_VERSION,
        save_slice_id: "save-slice-smoke".to_string(),
        source: RuntimeSaveSliceDocumentSource {
            description: Some("test save slice".to_string()),
            original_save_filename: Some("smoke.gms".to_string()),
            original_save_sha256: Some("deadbeef".to_string()),
            notes: vec!["captured fixture".to_string()],
        },
        save_slice: SmpLoadedSaveSlice {
            file_extension_hint: Some("gms".to_string()),
            container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
            mechanism_family: "classic-save-rehydrate-v1".to_string(),
            mechanism_confidence: "grounded".to_string(),
            trailer_family: None,
            bridge_family: None,
            profile: None,
            candidate_availability_table: None,
            named_locomotive_availability_table: None,
            locomotive_catalog: None,
            cargo_catalog: None,
            world_issue_37_state: None,
            world_economic_tuning_state: None,
            world_finance_neighborhood_state: None,
            world_locomotive_policy_state: None,
            company_roster: None,
            chairman_profile_table: None,
            region_collection: None,
            region_fixed_row_run_summary: None,
            placed_structure_collection: None,
            placed_structure_dynamic_side_buffer_summary: None,
            special_conditions_table: None,
            event_runtime_collection: None,
            notes: vec![],
        },
    };
    assert!(validate_runtime_save_slice_document(&document).is_ok());

    let path = write_temp_json("save-slice-doc", &document);
    save_runtime_save_slice_document(&path, &document).expect("save slice doc should save");
    let loaded = load_runtime_save_slice_document(&path).expect("save slice doc should load");
    assert_eq!(document, loaded);
    let _ = std::fs::remove_file(path);
}

#[test]
fn loads_save_slice_document_as_runtime_state_import() {
    let text = serde_json::to_string(&RuntimeSaveSliceDocument {
        format_version: SAVE_SLICE_DOCUMENT_FORMAT_VERSION,
        save_slice_id: "save-slice-import".to_string(),
        source: RuntimeSaveSliceDocumentSource {
            description: Some("test save slice import".to_string()),
            original_save_filename: Some("import.gms".to_string()),
            original_save_sha256: None,
            notes: vec![],
        },
        save_slice: SmpLoadedSaveSlice {
            file_extension_hint: Some("gms".to_string()),
            container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
            mechanism_family: "classic-save-rehydrate-v1".to_string(),
            mechanism_confidence: "grounded".to_string(),
            trailer_family: None,
            bridge_family: None,
            profile: None,
            candidate_availability_table: None,
            named_locomotive_availability_table: None,
            locomotive_catalog: None,
            cargo_catalog: None,
            world_issue_37_state: None,
            world_economic_tuning_state: None,
            world_finance_neighborhood_state: None,
            world_locomotive_policy_state: None,
            company_roster: None,
            chairman_profile_table: None,
            region_collection: None,
            region_fixed_row_run_summary: None,
            placed_structure_collection: None,
            placed_structure_dynamic_side_buffer_summary: None,
            special_conditions_table: None,
            event_runtime_collection: None,
            notes: vec![],
        },
    })
    .expect("save slice doc should serialize");

    let input = load_runtime_state_input_from_str(&text, "fallback")
        .expect("save slice document should load as runtime input");
    assert_eq!(input.input_id, "save-slice-import");
    assert_eq!(
        input
            .state
            .metadata
            .get("save_slice.import_projection")
            .map(String::as_str),
        Some("partial-runtime-restore-v1")
    );
}
