use super::*;

#[test]
fn exports_and_summarizes_runtime_snapshot() {
    let fixture = serde_json::json!({
        "format_version": 1,
        "fixture_id": "runtime-export-test",
        "source": { "kind": "synthetic" },
        "state": {
            "calendar": {
                "year": 1830,
                "month_slot": 0,
                "phase_slot": 0,
                "tick_slot": 0
            },
            "world_flags": {},
            "companies": [],
            "event_runtime_records": []
        },
        "commands": [
            {
                "kind": "step_count",
                "steps": 2
            }
        ],
        "expected_summary": {
            "calendar": {
                "year": 1830,
                "month_slot": 0,
                "phase_slot": 0,
                "tick_slot": 2
            },
            "world_flag_count": 0,
            "company_count": 0,
            "event_runtime_record_count": 0,
            "total_company_cash": 0
        }
    });
    let fixture_path = write_temp_json("runtime-export-fixture", &fixture);
    let snapshot_path = std::env::temp_dir().join(format!(
        "rrt-cli-runtime-export-{}.json",
        std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .expect("system time should be after epoch")
            .as_nanos()
    ));

    export_fixture_state(&fixture_path, &snapshot_path).expect("fixture export should succeed");
    summarize_state(&snapshot_path).expect("snapshot summary should succeed");

    let _ = fs::remove_file(fixture_path);
    let _ = fs::remove_file(snapshot_path);
}

#[test]
fn snapshots_runtime_state_input_into_snapshot() {
    let input = serde_json::json!({
        "format_version": 1,
        "input_id": "runtime-input-test",
        "source": {
            "description": "test runtime state input"
        },
        "state": {
            "calendar": {
                "year": 1830,
                "month_slot": 0,
                "phase_slot": 0,
                "tick_slot": 9
            },
            "world_flags": {},
            "companies": [],
            "event_runtime_records": [],
            "service_state": {
                "periodic_boundary_calls": 0,
                "trigger_dispatch_counts": {},
                "total_event_record_services": 0,
                "dirty_rerun_count": 0
            }
        }
    });
    let input_path = write_temp_json("runtime-input", &input);
    let output_path = std::env::temp_dir().join(format!(
        "rrt-cli-runtime-input-{}.json",
        std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .expect("system time should be after epoch")
            .as_nanos()
    ));

    snapshot_state(&input_path, &output_path).expect("runtime snapshot should succeed");
    summarize_state(&output_path).expect("snapshotted output should summarize");

    let _ = fs::remove_file(input_path);
    let _ = fs::remove_file(output_path);
}

#[test]
fn exports_runtime_save_slice_document_from_loaded_slice() {
    let nonce = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .expect("system time should be after epoch")
        .as_nanos();
    let output_path = std::env::temp_dir().join(format!("rrt-export-save-slice-test-{nonce}.json"));
    let smp_path = PathBuf::from("captured-test.gms");

    let report = export_runtime_save_slice_document(
        &smp_path,
        &output_path,
        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!["exported for test".to_string()],
        },
    )
    .expect("save slice export should succeed");

    assert_eq!(report.save_slice_id, "captured-test");
    let document = load_runtime_save_slice_document(&output_path)
        .expect("exported save slice document should load");
    assert_eq!(document.save_slice_id, "captured-test");
    assert_eq!(
        document.source.original_save_filename.as_deref(),
        Some("captured-test.gms")
    );
    let _ = fs::remove_file(output_path);
}

#[test]
fn exports_runtime_overlay_import_document() {
    let nonce = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .expect("system time should be after epoch")
        .as_nanos();
    let output_path =
        std::env::temp_dir().join(format!("rrt-export-overlay-import-test-{nonce}.json"));
    let snapshot_path = PathBuf::from("base-snapshot.json");
    let save_slice_path = PathBuf::from("captured-save-slice.json");

    let report =
        export_runtime_overlay_import_document(&snapshot_path, &save_slice_path, &output_path)
            .expect("overlay import export should succeed");

    let expected_import_id = output_path
        .file_stem()
        .and_then(|stem| stem.to_str())
        .expect("output path should have a stem")
        .to_string();
    assert_eq!(report.import_id, expected_import_id);
    let document = load_runtime_overlay_import_document(&output_path)
        .expect("exported overlay import document should load");
    assert_eq!(document.import_id, expected_import_id);
    assert_eq!(document.base_snapshot_path, "base-snapshot.json");
    assert_eq!(document.save_slice_path, "captured-save-slice.json");
    let _ = fs::remove_file(output_path);
}
