use super::*;

#[test]
fn projects_save_slice_into_runtime_state_import() {
    let save_slice = SmpLoadedSaveSlice {
        file_extension_hint: Some("gms".to_string()),
        container_profile_family: Some("rt3-105-save-container-v1".to_string()),
        mechanism_family: "rt3-105-save-post-span-bridge-v1".to_string(),
        mechanism_confidence: "mixed".to_string(),
        trailer_family: Some("rt3-105-save-trailer-v1".to_string()),
        bridge_family: Some("rt3-105-save-post-span-bridge-v1".to_string()),
        profile: Some(SmpLoadedProfile {
            profile_kind: "rt3-105-packed-profile".to_string(),
            profile_family: "rt3-105-save-container-v1".to_string(),
            packed_profile_offset: 0x73c0,
            packed_profile_len: 0x108,
            packed_profile_len_hex: "0x108".to_string(),
            leading_word_0: 3,
            leading_word_0_hex: "0x00000003".to_string(),
            header_flag_word_3: Some(0x01000000),
            header_flag_word_3_hex: Some("0x01000000".to_string()),
            map_path: Some("Alternate USA.gmp".to_string()),
            display_name: Some("Alternate USA".to_string()),
            profile_byte_0x77: 0x07,
            profile_byte_0x77_hex: "0x07".to_string(),
            profile_byte_0x82: 0x4d,
            profile_byte_0x82_hex: "0x4d".to_string(),
            profile_byte_0x97: 0x00,
            profile_byte_0x97_hex: "0x00".to_string(),
            profile_byte_0xc5: 0x00,
            profile_byte_0xc5_hex: "0x00".to_string(),
        }),
        candidate_availability_table: Some(SmpLoadedCandidateAvailabilityTable {
            source_kind: "save-bridge-secondary-block".to_string(),
            semantic_family: "scenario-named-candidate-availability-table".to_string(),
            header_offset: 0x6a70,
            entries_offset: 0x6ad1,
            entries_end_offset: 0x73b7,
            observed_entry_count: 2,
            zero_availability_count: 1,
            zero_availability_names: vec!["Uranium Mine".to_string()],
            footer_progress_hex_words: vec!["0x000032dc".to_string(), "0x00003714".to_string()],
            entries: vec![
                SmpRt3105SaveNameTableEntry {
                    index: 0,
                    offset: 0x6ad1,
                    text: "AutoPlant".to_string(),
                    availability_dword: 1,
                    availability_dword_hex: "0x00000001".to_string(),
                    trailer_word: 1,
                    trailer_word_hex: "0x00000001".to_string(),
                },
                SmpRt3105SaveNameTableEntry {
                    index: 1,
                    offset: 0x6af3,
                    text: "Uranium Mine".to_string(),
                    availability_dword: 0,
                    availability_dword_hex: "0x00000000".to_string(),
                    trailer_word: 0,
                    trailer_word_hex: "0x00000000".to_string(),
                },
            ],
        }),
        named_locomotive_availability_table: Some(SmpLoadedNamedLocomotiveAvailabilityTable {
            source_kind: "runtime-save-direct-serializer".to_string(),
            semantic_family: "scenario-named-locomotive-availability-table".to_string(),
            header_offset: None,
            entries_offset: None,
            entries_end_offset: None,
            observed_entry_count: 2,
            zero_availability_count: 1,
            zero_availability_names: vec!["Big Boy".to_string()],
            entries: vec![
                SmpRt3105SaveNameTableEntry {
                    index: 0,
                    offset: 0,
                    text: "Big Boy".to_string(),
                    availability_dword: 0,
                    availability_dword_hex: "0x00000000".to_string(),
                    trailer_word: 0,
                    trailer_word_hex: "0x00000000".to_string(),
                },
                SmpRt3105SaveNameTableEntry {
                    index: 1,
                    offset: 0x41,
                    text: "GP7".to_string(),
                    availability_dword: 1,
                    availability_dword_hex: "0x00000001".to_string(),
                    trailer_word: 1,
                    trailer_word_hex: "0x00000001".to_string(),
                },
            ],
        }),
        locomotive_catalog: None,
        cargo_catalog: Some(save_cargo_catalog(&[
            (1, crate::event::targets::RuntimeCargoClass::Factory),
            (5, crate::event::targets::RuntimeCargoClass::FarmMine),
            (9, crate::event::targets::RuntimeCargoClass::Other),
        ])),
        world_issue_37_state: Some(SmpLoadedWorldIssue37State {
            source_kind: "save-fixed-world-block".to_string(),
            semantic_family: "world-issue-0x37".to_string(),
            issue_value: 3,
            issue_value_hex: "0x00000003".to_string(),
            issue_38_value: 1,
            issue_38_value_hex: "0x01".to_string(),
            issue_39_value: 2,
            issue_39_value_hex: "0x02".to_string(),
            issue_3a_value: 4,
            issue_3a_value_hex: "0x04".to_string(),
            multiplier_raw_u32: 0x3d75c28f,
            multiplier_raw_hex: "0x3d75c28f".to_string(),
            multiplier_value_f32_text: "0.060000".to_string(),
            issue_opinion_base_terms_raw_i32: Vec::new(),
        }),
        world_economic_tuning_state: Some(SmpLoadedWorldEconomicTuningState {
            source_kind: "save-fixed-world-block".to_string(),
            semantic_family: "world-economic-tuning".to_string(),
            mirror_raw_u32: 0x3f46d093,
            mirror_raw_hex: "0x3f46d093".to_string(),
            mirror_value_f32_text: "0.776620".to_string(),
            lane_raw_u32: vec![0x3f400000, 0x3be56042],
            lane_raw_hex: vec!["0x3f400000".to_string(), "0x3be56042".to_string()],
            lane_value_f32_text: vec!["0.750000".to_string(), "0.007000".to_string()],
        }),
        world_finance_neighborhood_state: Some(SmpLoadedWorldFinanceNeighborhoodState {
            source_kind: "save-fixed-world-block".to_string(),
            semantic_family: "world-finance-neighborhood".to_string(),
            packed_year_word_raw_u16: 0x0201,
            packed_year_word_raw_hex: "0x0201".to_string(),
            partial_year_progress_raw_u8: 3,
            partial_year_progress_raw_hex: "0x03".to_string(),
            current_calendar_tuple_word_raw_u32: 1,
            current_calendar_tuple_word_raw_hex: "0x00000001".to_string(),
            current_calendar_tuple_word_2_raw_u32: 2,
            current_calendar_tuple_word_2_raw_hex: "0x00000002".to_string(),
            absolute_counter_raw_u32: 3,
            absolute_counter_raw_hex: "0x00000003".to_string(),
            absolute_counter_mirror_raw_u32: 4,
            absolute_counter_mirror_raw_hex: "0x00000004".to_string(),
            stock_policy_raw_u8: 0,
            stock_policy_raw_hex: "0x00".to_string(),
            bond_policy_raw_u8: 1,
            bond_policy_raw_hex: "0x01".to_string(),
            bankruptcy_policy_raw_u8: 0,
            bankruptcy_policy_raw_hex: "0x00".to_string(),
            dividend_policy_raw_u8: 1,
            dividend_policy_raw_hex: "0x01".to_string(),
            building_density_growth_setting_raw_u32: 1,
            building_density_growth_setting_raw_hex: "0x00000001".to_string(),
            labels: vec![
                "current_calendar_tuple_word".to_string(),
                "current_calendar_tuple_word_2".to_string(),
                "absolute_calendar_counter".to_string(),
                "absolute_calendar_counter_mirror".to_string(),
            ],
            relative_offsets: vec![0x0d, 0x11, 0x15, 0x19],
            relative_offset_hex: vec![
                "0xd".to_string(),
                "0x11".to_string(),
                "0x15".to_string(),
                "0x19".to_string(),
            ],
            raw_u32: vec![1, 2, 3, 4],
            raw_hex: vec![
                "0x00000001".to_string(),
                "0x00000002".to_string(),
                "0x00000003".to_string(),
                "0x00000004".to_string(),
            ],
            value_i32: vec![1, 2, 3, 4],
            value_f32_text: vec![
                "0.000000".to_string(),
                "0.000000".to_string(),
                "0.000000".to_string(),
                "0.000000".to_string(),
            ],
        }),
        world_locomotive_policy_state: Some(SmpLoadedWorldLocomotivePolicyState {
            source_kind: "save-fixed-world-block".to_string(),
            semantic_family: "world-locomotive-policy".to_string(),
            selected_year_gap_scalar_raw_u32: Some(0x3eaaaaab),
            selected_year_gap_scalar_raw_hex: Some("0x3eaaaaab".to_string()),
            selected_year_gap_scalar_value_f32_text: Some("0.333333".to_string()),
            linked_site_removal_follow_on_gate_raw_u8: Some(1),
            linked_site_removal_follow_on_gate_raw_hex: Some("0x01".to_string()),
            auto_show_grade_during_track_lay_raw_u8: Some(2),
            auto_show_grade_during_track_lay_raw_hex: Some("0x02".to_string()),
            starting_building_density_level_raw_u8: Some(3),
            starting_building_density_level_raw_hex: Some("0x03".to_string()),
            building_density_growth_raw_u8: Some(1),
            building_density_growth_raw_hex: Some("0x01".to_string()),
            leftover_simulation_time_accumulator_raw_u32: Some(0x3f000000),
            leftover_simulation_time_accumulator_raw_hex: Some("0x3f000000".to_string()),
            leftover_simulation_time_accumulator_value_f32_text: Some("0.500000".to_string()),
            selected_year_lane_snapshot_raw_u8: Some(7),
            selected_year_lane_snapshot_raw_hex: Some("0x07".to_string()),
            all_steam_locomotives_available_raw_u8: Some(1),
            all_steam_locomotives_available_raw_hex: Some("0x01".to_string()),
            all_diesel_locomotives_available_raw_u8: Some(0),
            all_diesel_locomotives_available_raw_hex: Some("0x00".to_string()),
            all_electric_locomotives_available_raw_u8: Some(1),
            all_electric_locomotives_available_raw_hex: Some("0x01".to_string()),
            cached_available_locomotive_rating_raw_u32: Some(0x41a00000),
            cached_available_locomotive_rating_raw_hex: Some("0x41a00000".to_string()),
            cached_available_locomotive_rating_value_f32_text: Some("20.000000".to_string()),
        }),
        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: Some(SmpLoadedSpecialConditionsTable {
            source_kind: "save-fixed-special-conditions-range".to_string(),
            table_offset: 0x0d64,
            table_len: 36 * 4,
            enabled_visible_count: 0,
            enabled_visible_labels: vec![],
            entries: vec![
                SmpSpecialConditionEntry {
                    slot_index: 30,
                    hidden: false,
                    label_id: 3722,
                    help_id: 3723,
                    label: "Disable Cargo Economy".to_string(),
                    value: 0,
                    value_hex: "0x00000000".to_string(),
                },
                SmpSpecialConditionEntry {
                    slot_index: 35,
                    hidden: true,
                    label_id: 3,
                    help_id: 3,
                    label: "Hidden sentinel".to_string(),
                    value: 1,
                    value_hex: "0x00000001".to_string(),
                },
            ],
        }),
        event_runtime_collection: Some(SmpLoadedEventRuntimeCollectionSummary {
            source_kind: "packed-event-runtime-collection".to_string(),
            mechanism_family: "rt3-105-save-post-span-bridge-v1".to_string(),
            mechanism_confidence: "mixed".to_string(),
            container_profile_family: Some("rt3-105-save-container-v1".to_string()),
            metadata_tag_offset: 0x7100,
            records_tag_offset: 0x7200,
            close_tag_offset: 0x7600,
            packed_state_version: 0x3e9,
            packed_state_version_hex: "0x000003e9".to_string(),
            live_id_bound: 5,
            live_record_count: 3,
            live_entry_ids: vec![1, 3, 5],
            decoded_record_count: 0,
            imported_runtime_record_count: 0,
            records_with_trigger_kind: 0,
            records_missing_trigger_kind: 0,
            nondirect_compact_record_count: 0,
            nondirect_compact_records_missing_trigger_kind: 0,
            trigger_kinds_present: vec![],
            control_lane_notes: vec![],
            add_building_dispatch_strip_record_indexes: vec![],
            add_building_dispatch_strip_descriptor_labels: vec![],
            add_building_dispatch_strip_records_with_trigger_kind: 0,
            add_building_dispatch_strip_records_missing_trigger_kind: 0,
            add_building_dispatch_strip_row_shape_families: vec![],
            add_building_dispatch_strip_signature_families: vec![],
            add_building_dispatch_strip_condition_tuple_families: vec![],
            add_building_dispatch_strip_signature_condition_clusters: vec![],
            records: vec![
                SmpLoadedPackedEventRecordSummary {
                    record_index: 0,
                    live_entry_id: 1,
                    payload_offset: None,
                    payload_len: None,
                    decode_status: "unsupported_framing".to_string(),
                    payload_family: "unsupported_framing".to_string(),
                    trigger_kind: None,
                    active: None,
                    marks_collection_dirty: None,
                    one_shot: None,
                    compact_control: None,
                    text_bands: Vec::new(),
                    standalone_condition_row_count: 0,
                    standalone_condition_rows: Vec::new(),
                    negative_sentinel_scope: None,
                    grouped_effect_row_counts: vec![0, 0, 0, 0],
                    grouped_effect_rows: Vec::new(),
                    decoded_conditions: Vec::new(),
                    decoded_actions: Vec::new(),
                    executable_import_ready: false,
                    notes: vec!["test".to_string()],
                },
                SmpLoadedPackedEventRecordSummary {
                    record_index: 1,
                    live_entry_id: 3,
                    payload_offset: None,
                    payload_len: None,
                    decode_status: "unsupported_framing".to_string(),
                    payload_family: "unsupported_framing".to_string(),
                    trigger_kind: None,
                    active: None,
                    marks_collection_dirty: None,
                    one_shot: None,
                    compact_control: None,
                    text_bands: Vec::new(),
                    standalone_condition_row_count: 0,
                    standalone_condition_rows: Vec::new(),
                    negative_sentinel_scope: None,
                    grouped_effect_row_counts: vec![0, 0, 0, 0],
                    grouped_effect_rows: Vec::new(),
                    decoded_conditions: Vec::new(),
                    decoded_actions: Vec::new(),
                    executable_import_ready: false,
                    notes: vec!["test".to_string()],
                },
                SmpLoadedPackedEventRecordSummary {
                    record_index: 2,
                    live_entry_id: 5,
                    payload_offset: None,
                    payload_len: None,
                    decode_status: "unsupported_framing".to_string(),
                    payload_family: "unsupported_framing".to_string(),
                    trigger_kind: None,
                    active: None,
                    marks_collection_dirty: None,
                    one_shot: None,
                    compact_control: None,
                    text_bands: Vec::new(),
                    standalone_condition_row_count: 0,
                    standalone_condition_rows: Vec::new(),
                    negative_sentinel_scope: None,
                    grouped_effect_row_counts: vec![0, 0, 0, 0],
                    grouped_effect_rows: Vec::new(),
                    decoded_conditions: Vec::new(),
                    decoded_actions: Vec::new(),
                    executable_import_ready: false,
                    notes: vec!["test".to_string()],
                },
            ],
        }),
        notes: vec!["packed profile recovered".to_string()],
    };

    let input = build_runtime_state_input_from_save_slice(
        &save_slice,
        "save-input-smoke",
        Some("test save input".to_string()),
    )
    .expect("save slice should project");

    assert_eq!(input.input_id, "save-input-smoke");
    assert_eq!(
        input
            .state
            .metadata
            .get("save_slice.map_path")
            .map(String::as_str),
        Some("Alternate USA.gmp")
    );
    assert_eq!(
        input.state.save_profile.selected_year_profile_lane,
        Some(0x07)
    );
    assert_eq!(input.state.save_profile.sandbox_enabled, Some(true));
    assert_eq!(
        input.state.world_restore.selected_year_profile_lane,
        Some(0x07)
    );
    assert_eq!(input.state.world_restore.sandbox_enabled, Some(true));
    assert_eq!(
        input.state.world_restore.campaign_scenario_enabled,
        Some(false)
    );
    assert_eq!(
        input.state.world_restore.seed_tuple_written_from_raw_lane,
        Some(true)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .absolute_counter_requires_shell_context,
        Some(false)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .absolute_counter_reconstructible_from_save,
        Some(true)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .auto_show_grade_during_track_lay_raw_u8,
        Some(2)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .starting_building_density_level_raw_u8,
        Some(3)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .post_text_building_density_growth_raw_u8,
        Some(1)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .leftover_simulation_time_accumulator_raw_u32,
        Some(0x3f000000)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .leftover_simulation_time_accumulator_value_f32_text
            .as_deref(),
        Some("0.500000")
    );
    assert_eq!(
        input.state.world_restore.selected_year_lane_snapshot_raw_u8,
        Some(7)
    );
    assert_eq!(
        input.state.world_restore.packed_year_word_raw_u16,
        Some(0x0201)
    );
    assert_eq!(
        input.state.world_restore.partial_year_progress_raw_u8,
        Some(3)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .current_calendar_tuple_word_raw_u32,
        Some(1)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .current_calendar_tuple_word_2_raw_u32,
        Some(2)
    );
    assert_eq!(input.state.world_restore.absolute_counter_raw_u32, Some(3));
    assert_eq!(
        input.state.world_restore.absolute_counter_mirror_raw_u32,
        Some(4)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .disable_cargo_economy_special_condition_slot,
        Some(30)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .disable_cargo_economy_special_condition_reconstructible_from_save,
        Some(true)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .disable_cargo_economy_special_condition_write_side_grounded,
        Some(true)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .disable_cargo_economy_special_condition_enabled,
        Some(false)
    );
    assert_eq!(
        input.state.world_restore.use_bio_accelerator_cars_enabled,
        Some(false)
    );
    assert_eq!(
        input.state.world_restore.use_wartime_cargos_enabled,
        Some(false)
    );
    assert_eq!(
        input.state.world_restore.disable_train_crashes_enabled,
        Some(false)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .disable_train_crashes_and_breakdowns_enabled,
        Some(false)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .ai_ignore_territories_at_startup_enabled,
        Some(false)
    );
    assert_eq!(input.state.world_restore.issue_37_value, Some(3));
    assert_eq!(input.state.world_restore.issue_38_value, Some(1));
    assert_eq!(input.state.world_restore.issue_39_value, Some(2));
    assert_eq!(input.state.world_restore.issue_3a_value, Some(4));
    assert_eq!(
        input.state.world_restore.issue_37_multiplier_raw_u32,
        Some(0x3d75c28f)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .stock_issue_and_buyback_policy_raw_u8,
        Some(0)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .bond_issue_and_repayment_policy_raw_u8,
        Some(1)
    );
    assert_eq!(input.state.world_restore.bankruptcy_policy_raw_u8, Some(0));
    assert_eq!(input.state.world_restore.dividend_policy_raw_u8, Some(1));
    assert_eq!(
        input.state.world_restore.stock_issue_and_buyback_allowed,
        Some(true)
    );
    assert_eq!(
        input.state.world_restore.bond_issue_and_repayment_allowed,
        Some(false)
    );
    assert_eq!(input.state.world_restore.bankruptcy_allowed, Some(true));
    assert_eq!(
        input.state.world_restore.dividend_adjustment_allowed,
        Some(false)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .issue_37_multiplier_value_f32_text
            .as_deref(),
        Some("0.060000")
    );
    assert_eq!(
        input.state.world_restore.economic_tuning_mirror_raw_u32,
        Some(0x3f400000)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .economic_tuning_mirror_value_f32_text
            .as_deref(),
        Some("0.750000")
    );
    assert_eq!(
        input.state.world_restore.economic_tuning_lane_raw_u32,
        vec![0x3f400000, 0x3be56042]
    );
    assert_eq!(
        input
            .state
            .world_restore
            .economic_tuning_lane_value_f32_text,
        vec!["0.750000".to_string(), "0.007000".to_string()]
    );
    assert_eq!(
        input
            .state
            .world_restore
            .linked_site_removal_follow_on_gate_raw_u8,
        Some(1)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .all_steam_locomotives_available_enabled,
        Some(true)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .all_diesel_locomotives_available_enabled,
        Some(false)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .all_electric_locomotives_available_enabled,
        Some(true)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .cached_available_locomotive_rating_raw_u32,
        Some(0x41a00000)
    );
    assert_eq!(
        input
            .state
            .world_restore
            .absolute_counter_restore_kind
            .as_deref(),
        Some("save-direct-world-absolute-counter")
    );
    assert_eq!(
        input
            .state
            .world_restore
            .absolute_counter_adjustment_context
            .as_deref(),
        Some("save-direct-world-block-0x32c8")
    );
    assert_eq!(
        input.state.save_profile.map_path.as_deref(),
        Some("Alternate USA.gmp")
    );
    assert_eq!(
        input.state.candidate_availability.get("Uranium Mine"),
        Some(&0)
    );
    assert_eq!(
        input.state.named_locomotive_availability.get("Big Boy"),
        Some(&0)
    );
    assert_eq!(
        input.state.named_locomotive_availability.get("GP7"),
        Some(&1)
    );
    assert_eq!(input.state.locomotive_catalog.len(), 2);
    assert_eq!(input.state.locomotive_catalog[0].locomotive_id, 1);
    assert_eq!(input.state.locomotive_catalog[0].name, "Big Boy");
    assert_eq!(input.state.locomotive_catalog[1].locomotive_id, 2);
    assert_eq!(input.state.locomotive_catalog[1].name, "GP7");
    assert_eq!(
        input.state.special_conditions.get("Disable Cargo Economy"),
        Some(&0)
    );
    assert_eq!(
        input
            .state
            .metadata
            .get("save_slice.world_issue_37_value")
            .map(String::as_str),
        Some("3")
    );
    assert_eq!(
        input
            .state
            .metadata
            .get("save_slice.world_issue_39_value")
            .map(String::as_str),
        Some("2")
    );
    assert_eq!(
        input
            .state
            .metadata
            .get("save_slice.world_economic_tuning_lane_count")
            .map(String::as_str),
        Some("2")
    );
    assert_eq!(
        input
            .state
            .world_flags
            .get("save_slice.world_issue_37_state_present"),
        Some(&true)
    );
    assert_eq!(
        input
            .state
            .world_flags
            .get("save_slice.world_economic_tuning_state_present"),
        Some(&true)
    );
    assert_eq!(
        input
            .state
            .metadata
            .get("save_slice.named_locomotive_availability_source_kind")
            .map(String::as_str),
        Some("runtime-save-direct-serializer")
    );
    assert_eq!(
        input
            .state
            .metadata
            .get("save_slice.named_locomotive_availability_entry_count")
            .map(String::as_str),
        Some("2")
    );
    assert_eq!(
        input
            .state
            .metadata
            .get("save_slice.locomotive_catalog_source_kind")
            .map(String::as_str),
        Some("derived-from-named-locomotive-availability-table")
    );
    assert_eq!(
        input
            .state
            .world_flags
            .get("save_slice.profile_byte_0x82_nonzero"),
        Some(&true)
    );
    assert_eq!(
        input
            .state
            .packed_event_collection
            .as_ref()
            .map(|summary| summary.live_record_count),
        Some(3)
    );
    assert_eq!(
        input
            .state
            .packed_event_collection
            .as_ref()
            .map(|summary| summary.live_entry_ids.clone()),
        Some(vec![1, 3, 5])
    );
    assert!(input.state.event_runtime_records.is_empty());
}

#[test]
fn projects_near_city_acquisition_runtime_slice_from_save_collections() {
    let save_slice = SmpLoadedSaveSlice {
        file_extension_hint: Some("gms".to_string()),
        container_profile_family: Some("rt3-105-save-container-v1".to_string()),
        mechanism_family: "rt3-105-save-post-span-bridge-v1".to_string(),
        mechanism_confidence: "mixed".to_string(),
        trailer_family: Some("rt3-105-save-trailer-v1".to_string()),
        bridge_family: Some("rt3-105-save-post-span-bridge-v1".to_string()),
        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: Some(save_company_roster()),
        chairman_profile_table: Some(save_chairman_profile_table()),
        region_collection: Some(save_region_collection()),
        region_fixed_row_run_summary: Some(save_region_fixed_row_run_summary()),
        placed_structure_collection: Some(save_placed_structure_collection()),
        placed_structure_dynamic_side_buffer_summary: Some(
            save_placed_structure_dynamic_side_buffer_summary(),
        ),
        special_conditions_table: None,
        event_runtime_collection: None,
        notes: vec![],
    };

    let input =
        build_runtime_state_input_from_save_slice(&save_slice, "near-city-projection", None)
            .expect("save slice projection should succeed");

    assert_eq!(
        input
            .state
            .service_state
            .near_city_acquisition_regions
            .len(),
        2
    );
    assert_eq!(
        input.state.service_state.near_city_acquisition_sites.len(),
        2
    );
    assert_eq!(
        input.state.service_state.near_city_acquisition_sites[0].region_id,
        Some(0)
    );
    assert_eq!(
        input.state.service_state.near_city_acquisition_sites[0].owner_company_id,
        Some(1)
    );
    assert_eq!(
        input.state.service_state.near_city_acquisition_sites[0].candidate_subtype_label,
        "farm"
    );
    assert_eq!(
        input.state.service_state.near_city_acquisition_sites[0].cached_tri_lane_0,
        0xff0000ff
    );
    assert_eq!(
        input.state.service_state.near_city_acquisition_sites[0].cached_tri_lane_2,
        0x24
    );
}
