use std::collections::BTreeMap;

use crate::event::metrics::*;
use crate::event::news::*;
use crate::event::packed::*;
use crate::state::*;
use crate::{CalendarPoint, RuntimeState};

use super::RuntimeSummary;

#[test]
fn counts_structural_only_and_missing_context_frontiers() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            auto_show_grade_during_track_lay_raw_u8: Some(2),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: Vec::new(),
        selected_company_id: None,
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: vec![crate::state::RuntimeChairmanProfile {
            profile_id: 1,
            name: "Chairman One".to_string(),
            active: true,
            current_cash: 0,
            linked_company_id: Some(1),
            company_holdings: std::collections::BTreeMap::from([(1, 5_000)]),
            holdings_value_total: 0,
            net_worth_total: 0,
            purchasing_power_total: 0,
        }],
        selected_chairman_profile_id: Some(1),
        trains: Vec::new(),
        locomotive_catalog: vec![
            crate::state::RuntimeLocomotiveCatalogEntry {
                locomotive_id: 10,
                name: "Big Boy 4-8-8-4".to_string(),
            },
            crate::state::RuntimeLocomotiveCatalogEntry {
                locomotive_id: 58,
                name: "VL80T".to_string(),
            },
        ],
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: Some(RuntimePackedEventCollectionSummary {
            source_kind: "packed-event-runtime-collection".to_string(),
            mechanism_family: "classic-save-rehydrate-v1".to_string(),
            mechanism_confidence: "grounded".to_string(),
            container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
            packed_state_version: 0x3e9,
            packed_state_version_hex: "0x000003e9".to_string(),
            live_id_bound: 11,
            live_record_count: 5,
            live_entry_ids: vec![3, 7, 9, 10, 11],
            decoded_record_count: 5,
            imported_runtime_record_count: 0,
            records: vec![
                RuntimePackedEventRecordSummary {
                    record_index: 0,
                    live_entry_id: 3,
                    payload_offset: Some(0x7202),
                    payload_len: Some(96),
                    decode_status: "parity_only".to_string(),
                    payload_family: "real_packed_v1".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(),
                    grouped_company_targets: Vec::new(),
                    decoded_conditions: Vec::new(),
                    decoded_actions: Vec::new(),
                    executable_import_ready: false,
                    import_outcome: Some("blocked_missing_compact_control".to_string()),
                    notes: Vec::new(),
                },
                RuntimePackedEventRecordSummary {
                    record_index: 1,
                    live_entry_id: 7,
                    payload_offset: Some(0x7262),
                    payload_len: Some(48),
                    decode_status: "parity_only".to_string(),
                    payload_family: "synthetic_harness".to_string(),
                    trigger_kind: Some(7),
                    active: Some(true),
                    marks_collection_dirty: Some(false),
                    one_shot: Some(false),
                    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(),
                    grouped_company_targets: Vec::new(),
                    decoded_conditions: Vec::new(),
                    decoded_actions: Vec::new(),
                    executable_import_ready: false,
                    import_outcome: Some("blocked_missing_company_context".to_string()),
                    notes: Vec::new(),
                },
                RuntimePackedEventRecordSummary {
                    record_index: 2,
                    live_entry_id: 9,
                    payload_offset: Some(0x7292),
                    payload_len: Some(48),
                    decode_status: "parity_only".to_string(),
                    payload_family: "real_packed_v1".to_string(),
                    trigger_kind: Some(7),
                    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(),
                    grouped_company_targets: Vec::new(),
                    decoded_conditions: Vec::new(),
                    decoded_actions: Vec::new(),
                    executable_import_ready: false,
                    import_outcome: Some("blocked_company_condition_scope_disabled".to_string()),
                    notes: Vec::new(),
                },
                RuntimePackedEventRecordSummary {
                    record_index: 3,
                    live_entry_id: 10,
                    payload_offset: Some(0x72c2),
                    payload_len: Some(48),
                    decode_status: "parity_only".to_string(),
                    payload_family: "real_packed_v1".to_string(),
                    trigger_kind: Some(7),
                    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(),
                    grouped_company_targets: Vec::new(),
                    decoded_conditions: Vec::new(),
                    decoded_actions: Vec::new(),
                    executable_import_ready: false,
                    import_outcome: Some("blocked_player_condition_scope".to_string()),
                    notes: Vec::new(),
                },
                RuntimePackedEventRecordSummary {
                    record_index: 4,
                    live_entry_id: 11,
                    payload_offset: Some(0x72f2),
                    payload_len: Some(48),
                    decode_status: "parity_only".to_string(),
                    payload_family: "real_packed_v1".to_string(),
                    trigger_kind: Some(7),
                    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(),
                    grouped_company_targets: Vec::new(),
                    decoded_conditions: Vec::new(),
                    decoded_actions: Vec::new(),
                    executable_import_ready: false,
                    import_outcome: Some("blocked_territory_condition_scope".to_string()),
                    notes: Vec::new(),
                },
            ],
        }),
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState::default(),
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(
        summary.packed_event_blocked_missing_compact_control_count,
        1
    );
    assert_eq!(
        summary.packed_event_blocked_unmapped_real_descriptor_count,
        0
    );
    assert_eq!(summary.packed_event_blocked_structural_only_count, 0);
    assert_eq!(
        summary.packed_event_blocked_missing_company_context_count,
        1
    );
    assert_eq!(
        summary.packed_event_blocked_missing_selection_context_count,
        0
    );
    assert_eq!(
        summary.packed_event_blocked_missing_company_role_context_count,
        0
    );
    assert_eq!(
        summary.packed_event_blocked_missing_condition_context_count,
        0
    );
    assert_eq!(
        summary.packed_event_blocked_company_condition_scope_disabled_count,
        1
    );
    assert_eq!(summary.packed_event_blocked_player_condition_scope_count, 1);
    assert_eq!(
        summary.packed_event_blocked_territory_condition_scope_count,
        1
    );
}

#[test]
fn summarizes_save_world_issue_and_economic_tuning_restore_state() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(0x0201),
            partial_year_progress_raw_u8: Some(3),
            current_calendar_tuple_word_raw_u32: Some(0x0108_0210),
            current_calendar_tuple_word_2_raw_u32: Some(0x35e6_3160),
            absolute_counter_raw_u32: Some(5),
            absolute_counter_mirror_raw_u32: Some(5),
            issue_37_value: Some(3),
            issue_38_value: Some(1),
            issue_39_value: Some(2),
            issue_3a_value: Some(4),
            issue_37_multiplier_raw_u32: Some(0x3d75c28f),
            issue_37_multiplier_value_f32_text: Some("0.06".to_string()),
            stock_issue_and_buyback_policy_raw_u8: Some(0),
            bond_issue_and_repayment_policy_raw_u8: Some(1),
            bankruptcy_policy_raw_u8: Some(0),
            dividend_policy_raw_u8: Some(1),
            stock_issue_and_buyback_allowed: Some(true),
            bond_issue_and_repayment_allowed: Some(false),
            bankruptcy_allowed: Some(true),
            dividend_adjustment_allowed: Some(false),
            economic_tuning_mirror_raw_u32: Some(0x3f46dff5),
            economic_tuning_mirror_value_f32_text: Some("0.7766201".to_string()),
            economic_tuning_lane_raw_u32: vec![
                0x3f400000, 0x3be56042, 0x3c03126f, 0x3c1374bc, 0x3c23d70a, 0x3c23d70a,
            ],
            economic_tuning_lane_value_f32_text: vec![
                "0.75".to_string(),
                "0.007".to_string(),
                "0.008".to_string(),
                "0.009".to_string(),
                "0.01".to_string(),
                "0.01".to_string(),
            ],
            linked_site_removal_follow_on_gate_raw_u8: Some(1),
            linked_site_removal_follow_on_gate_enabled: Some(true),
            auto_show_grade_during_track_lay_raw_u8: Some(2),
            starting_building_density_level_raw_u8: Some(3),
            post_text_building_density_growth_raw_u8: Some(1),
            leftover_simulation_time_accumulator_raw_u32: Some(0x3f000000),
            leftover_simulation_time_accumulator_value_f32_text: Some("0.500000".to_string()),
            selected_year_lane_snapshot_raw_u8: Some(7),
            all_steam_locomotives_available_raw_u8: Some(1),
            all_steam_locomotives_available_enabled: Some(true),
            all_diesel_locomotives_available_raw_u8: Some(0),
            all_diesel_locomotives_available_enabled: Some(false),
            all_electric_locomotives_available_raw_u8: Some(1),
            all_electric_locomotives_available_enabled: Some(true),
            cached_available_locomotive_rating_raw_u32: Some(0x41a00000),
            cached_available_locomotive_rating_value_f32_text: Some("20.000000".to_string()),
            selected_year_bucket_scalar_raw_u32: Some(25.0f32.to_bits()),
            selected_year_bucket_scalar_value_f32_text: Some("25.000000".to_string()),
            selected_year_bucket_direct_lane_raw_u32: vec![
                22.5f32.to_bits(),
                26.25f32.to_bits(),
                17.5f32.to_bits(),
            ],
            selected_year_bucket_direct_lane_value_f32_text: vec![
                "22.500000".to_string(),
                "26.250000".to_string(),
                "17.500000".to_string(),
            ],
            selected_year_bucket_complement_lane_raw_u32: vec![
                0.999121f32.to_bits(),
                0.998998f32.to_bits(),
                0.999210f32.to_bits(),
            ],
            selected_year_bucket_complement_lane_value_f32_text: vec![
                "0.999121".to_string(),
                "0.998998".to_string(),
                "0.999210".to_string(),
            ],
            selected_year_bucket_scaled_companion_lane_raw_u32: vec![
                139.16667f32.to_bits(),
                122.5f32.to_bits(),
                171.42857f32.to_bits(),
            ],
            selected_year_bucket_scaled_companion_lane_value_f32_text: vec![
                "139.166672".to_string(),
                "122.500000".to_string(),
                "171.428574".to_string(),
            ],
            selected_year_gap_scalar_raw_u32: Some(0x3eaaaaab),
            selected_year_gap_scalar_value_f32_text: Some("0.333333".to_string()),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: Vec::new(),
        selected_company_id: None,
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: vec![crate::state::RuntimeChairmanProfile {
            profile_id: 1,
            name: "Chairman One".to_string(),
            active: true,
            current_cash: 0,
            linked_company_id: Some(1),
            company_holdings: std::collections::BTreeMap::from([(1, 5_000)]),
            holdings_value_total: 0,
            net_worth_total: 0,
            purchasing_power_total: 0,
        }],
        selected_chairman_profile_id: Some(1),
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState::default(),
    };

    let summary = RuntimeSummary::from_state(&state);

    assert_eq!(summary.world_restore_packed_year_word_raw_u16, Some(0x0201));
    assert_eq!(summary.world_restore_partial_year_progress_raw_u8, Some(3));
    assert_eq!(
        summary.world_restore_current_calendar_tuple_word_raw_u32,
        Some(0x0108_0210)
    );
    assert_eq!(
        summary.world_restore_current_calendar_tuple_word_2_raw_u32,
        Some(0x35e6_3160)
    );
    assert_eq!(summary.world_restore_absolute_counter_raw_u32, Some(5));
    assert_eq!(
        summary.world_restore_absolute_counter_mirror_raw_u32,
        Some(5)
    );
    assert_eq!(summary.world_restore_issue_37_value, Some(3));
    assert_eq!(summary.world_restore_issue_38_value, Some(1));
    assert_eq!(summary.world_restore_issue_39_value, Some(2));
    assert_eq!(summary.world_restore_issue_3a_value, Some(4));
    assert_eq!(
        summary.world_restore_issue_37_multiplier_raw_u32,
        Some(0x3d75c28f)
    );
    assert_eq!(
        summary.world_restore_stock_issue_and_buyback_policy_raw_u8,
        Some(0)
    );
    assert_eq!(
        summary.world_restore_bond_issue_and_repayment_policy_raw_u8,
        Some(1)
    );
    assert_eq!(summary.world_restore_bankruptcy_policy_raw_u8, Some(0));
    assert_eq!(summary.world_restore_dividend_policy_raw_u8, Some(1));
    assert_eq!(
        summary.world_restore_stock_issue_and_buyback_allowed,
        Some(true)
    );
    assert_eq!(
        summary.world_restore_bond_issue_and_repayment_allowed,
        Some(false)
    );
    assert_eq!(summary.world_restore_bankruptcy_allowed, Some(true));
    assert_eq!(
        summary.world_restore_dividend_adjustment_allowed,
        Some(false)
    );
    assert_eq!(
        summary
            .world_restore_issue_37_multiplier_value_f32_text
            .as_deref(),
        Some("0.06")
    );
    assert_eq!(
        summary.world_restore_economic_tuning_mirror_raw_u32,
        Some(0x3f46dff5)
    );
    assert_eq!(
        summary
            .world_restore_economic_tuning_mirror_value_f32_text
            .as_deref(),
        Some("0.7766201")
    );
    assert_eq!(
        summary.world_restore_linked_site_removal_follow_on_gate_raw_u8,
        Some(1)
    );
    assert_eq!(
        summary.world_restore_linked_site_removal_follow_on_gate_enabled,
        Some(true)
    );
    assert_eq!(
        summary.world_restore_auto_show_grade_during_track_lay_raw_u8,
        Some(2)
    );
    assert_eq!(
        summary.world_restore_starting_building_density_level_raw_u8,
        Some(3)
    );
    assert_eq!(
        summary.world_restore_post_text_building_density_growth_raw_u8,
        Some(1)
    );
    assert_eq!(
        summary.world_restore_leftover_simulation_time_accumulator_raw_u32,
        Some(0x3f000000)
    );
    assert_eq!(
        summary
            .world_restore_leftover_simulation_time_accumulator_value_f32_text
            .as_deref(),
        Some("0.500000")
    );
    assert_eq!(
        summary.world_restore_selected_year_lane_snapshot_raw_u8,
        Some(7)
    );
    assert_eq!(
        summary.world_restore_all_steam_locomotives_available_raw_u8,
        Some(1)
    );
    assert_eq!(
        summary.world_restore_all_steam_locomotives_available_enabled,
        Some(true)
    );
    assert_eq!(
        summary.world_restore_all_diesel_locomotives_available_raw_u8,
        Some(0)
    );
    assert_eq!(
        summary.world_restore_all_diesel_locomotives_available_enabled,
        Some(false)
    );
    assert_eq!(
        summary.world_restore_all_electric_locomotives_available_raw_u8,
        Some(1)
    );
    assert_eq!(
        summary.world_restore_all_electric_locomotives_available_enabled,
        Some(true)
    );
    assert_eq!(
        summary.world_restore_cached_available_locomotive_rating_raw_u32,
        Some(0x41a00000)
    );
    assert_eq!(
        summary
            .world_restore_cached_available_locomotive_rating_value_f32_text
            .as_deref(),
        Some("20.000000")
    );
    assert_eq!(
        summary.world_restore_selected_year_bucket_scalar_raw_u32,
        Some(25.0f32.to_bits())
    );
    assert_eq!(
        summary
            .world_restore_selected_year_bucket_scalar_value_f32_text
            .as_deref(),
        Some("25.000000")
    );
    assert_eq!(
        summary.world_restore_selected_year_bucket_direct_lane_count,
        3
    );
    assert_eq!(
        summary.world_restore_selected_year_bucket_direct_lane_value_f32_text,
        vec!["22.500000", "26.250000", "17.500000"]
    );
    assert_eq!(
        summary.world_restore_selected_year_bucket_complement_lane_count,
        3
    );
    assert_eq!(
        summary.world_restore_selected_year_bucket_complement_lane_value_f32_text,
        vec!["0.999121", "0.998998", "0.999210"]
    );
    assert_eq!(
        summary.world_restore_selected_year_bucket_scaled_companion_lane_count,
        3
    );
    assert_eq!(
        summary.world_restore_selected_year_bucket_scaled_companion_lane_value_f32_text,
        vec!["139.166672", "122.500000", "171.428574"]
    );
    assert_eq!(summary.world_restore_economic_tuning_lane_count, 6);
    assert_eq!(
        summary.world_restore_economic_tuning_lane_value_f32_text,
        vec!["0.75", "0.007", "0.008", "0.009", "0.01", "0.01"]
    );
    assert_eq!(
        summary.world_restore_selected_year_gap_scalar_raw_u32,
        Some(0x3eaaaaab)
    );
    assert_eq!(
        summary
            .world_restore_selected_year_gap_scalar_value_f32_text
            .as_deref(),
        Some("0.333333")
    );
}

#[test]
fn counts_active_companies_separately_from_total_companies() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            auto_show_grade_during_track_lay_raw_u8: Some(2),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![
            RuntimeCompany {
                company_id: 1,
                current_cash: 10,
                debt: 0,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: RuntimeTrackPieceCounts::default(),
                active: true,
                available_track_laying_capacity: None,
                linked_chairman_profile_id: None,
                book_value_per_share: 0,
                investor_confidence: 0,
                management_attitude: 0,
                takeover_cooldown_year: None,
                merger_cooldown_year: None,
                controller_kind: RuntimeCompanyControllerKind::Human,
            },
            RuntimeCompany {
                company_id: 2,
                current_cash: 20,
                debt: 0,
                credit_rating_score: None,
                prime_rate: None,
                track_piece_counts: RuntimeTrackPieceCounts::default(),
                active: false,
                available_track_laying_capacity: Some(7),
                linked_chairman_profile_id: None,
                book_value_per_share: 0,
                investor_confidence: 0,
                management_attitude: 0,
                takeover_cooldown_year: None,
                merger_cooldown_year: None,
                controller_kind: RuntimeCompanyControllerKind::Ai,
            },
        ],
        selected_company_id: None,
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: vec![crate::state::RuntimeChairmanProfile {
            profile_id: 1,
            name: "Chairman One".to_string(),
            active: true,
            current_cash: 0,
            linked_company_id: Some(1),
            company_holdings: std::collections::BTreeMap::from([(1, 5_000)]),
            holdings_value_total: 0,
            net_worth_total: 0,
            purchasing_power_total: 0,
        }],
        selected_chairman_profile_id: Some(1),
        trains: Vec::new(),
        locomotive_catalog: vec![
            crate::state::RuntimeLocomotiveCatalogEntry {
                locomotive_id: 10,
                name: "Big Boy 4-8-8-4".to_string(),
            },
            crate::state::RuntimeLocomotiveCatalogEntry {
                locomotive_id: 58,
                name: "VL80T".to_string(),
            },
        ],
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState::default(),
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(summary.company_count, 2);
    assert_eq!(summary.active_company_count, 1);
}

#[test]
fn counts_named_locomotive_availability_entries_and_zero_values() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            auto_show_grade_during_track_lay_raw_u8: Some(2),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: Vec::new(),
        selected_company_id: None,
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: vec![
            crate::state::RuntimeLocomotiveCatalogEntry {
                locomotive_id: 10,
                name: "Big Boy 4-8-8-4".to_string(),
            },
            crate::state::RuntimeLocomotiveCatalogEntry {
                locomotive_id: 58,
                name: "VL80T".to_string(),
            },
        ],
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::from([
            ("Big Boy".to_string(), 0),
            ("GP7".to_string(), 1),
            ("Mikado".to_string(), 0),
        ]),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState::default(),
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(summary.locomotive_catalog_count, 2);
    assert_eq!(summary.named_locomotive_availability_count, 3);
    assert_eq!(summary.zero_named_locomotive_availability_count, 2);
    assert_eq!(summary.named_locomotive_cost_count, 0);
}

#[test]
fn counts_named_locomotive_cost_entries() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState::default(),
        metadata: BTreeMap::new(),
        companies: Vec::new(),
        selected_company_id: None,
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::from([
            ("Big Boy".to_string(), 250000),
            ("GP7".to_string(), 175000),
        ]),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState::default(),
    };

    let summary = RuntimeSummary::from_state(&state);

    assert_eq!(summary.named_locomotive_cost_count, 2);
}

#[test]
fn counts_world_scalar_override_surfaces() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            territory_access_cost: Some(750000),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: Vec::new(),
        selected_company_id: None,
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::from([(1, 125), (2, 250)]),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState::default(),
    };

    let summary = RuntimeSummary::from_state(&state);

    assert_eq!(summary.cargo_production_override_count, 2);
    assert_eq!(summary.world_restore_territory_access_cost, Some(750000));
}

#[test]
fn counts_runtime_variable_surfaces() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState::default(),
        metadata: BTreeMap::new(),
        companies: vec![RuntimeCompany {
            company_id: 1,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            active: true,
            available_track_laying_capacity: None,
            controller_kind: RuntimeCompanyControllerKind::Human,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
        }],
        selected_company_id: None,
        players: vec![RuntimePlayer {
            player_id: 2,
            current_cash: 0,
            active: true,
            controller_kind: RuntimeCompanyControllerKind::Human,
        }],
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: vec![RuntimeTerritory {
            territory_id: 3,
            name: Some("East".to_string()),
            track_piece_counts: RuntimeTrackPieceCounts::default(),
        }],
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::from([(1, 9)]),
        company_runtime_variables: BTreeMap::from([(1, BTreeMap::from([(2, 11)]))]),
        player_runtime_variables: BTreeMap::from([(2, BTreeMap::from([(3, 13)]))]),
        territory_runtime_variables: BTreeMap::from([(3, BTreeMap::from([(4, 15)]))]),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState::default(),
    };

    let summary = RuntimeSummary::from_state(&state);

    assert_eq!(summary.world_runtime_variable_count, 1);
    assert_eq!(summary.company_runtime_variable_owner_count, 1);
    assert_eq!(summary.player_runtime_variable_owner_count, 1);
    assert_eq!(summary.territory_runtime_variable_owner_count, 1);
}

#[test]
fn counts_world_frontier_buckets_separately() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState::default(),
        metadata: BTreeMap::new(),
        companies: Vec::new(),
        selected_company_id: None,
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: Some(RuntimePackedEventCollectionSummary {
            source_kind: "packed-event-runtime-collection".to_string(),
            mechanism_family: "classic-save-rehydrate-v1".to_string(),
            mechanism_confidence: "grounded".to_string(),
            container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
            packed_state_version: 0x3e9,
            packed_state_version_hex: "0x000003e9".to_string(),
            live_id_bound: 2,
            live_record_count: 2,
            live_entry_ids: vec![21, 22],
            decoded_record_count: 2,
            imported_runtime_record_count: 0,
            records: vec![
                RuntimePackedEventRecordSummary {
                    record_index: 0,
                    live_entry_id: 21,
                    payload_offset: Some(0x7202),
                    payload_len: Some(96),
                    decode_status: "parity_only".to_string(),
                    payload_family: "real_packed_v1".to_string(),
                    trigger_kind: Some(7),
                    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![1, 0, 0, 0],
                    grouped_effect_rows: Vec::new(),
                    grouped_company_targets: Vec::new(),
                    decoded_conditions: Vec::new(),
                    decoded_actions: Vec::new(),
                    executable_import_ready: false,
                    import_outcome: Some("blocked_unmapped_world_descriptor".to_string()),
                    notes: Vec::new(),
                },
                RuntimePackedEventRecordSummary {
                    record_index: 1,
                    live_entry_id: 22,
                    payload_offset: Some(0x7242),
                    payload_len: Some(96),
                    decode_status: "parity_only".to_string(),
                    payload_family: "real_packed_v1".to_string(),
                    trigger_kind: Some(7),
                    active: None,
                    marks_collection_dirty: None,
                    one_shot: None,
                    compact_control: None,
                    text_bands: Vec::new(),
                    standalone_condition_row_count: 1,
                    standalone_condition_rows: Vec::new(),
                    negative_sentinel_scope: None,
                    grouped_effect_row_counts: vec![0, 0, 0, 0],
                    grouped_effect_rows: Vec::new(),
                    grouped_company_targets: Vec::new(),
                    decoded_conditions: Vec::new(),
                    decoded_actions: Vec::new(),
                    executable_import_ready: false,
                    import_outcome: Some("blocked_unmapped_world_condition".to_string()),
                    notes: Vec::new(),
                },
            ],
        }),
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState::default(),
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(
        summary.packed_event_blocked_unmapped_world_descriptor_count,
        1
    );
    assert_eq!(
        summary.packed_event_blocked_unmapped_world_condition_count,
        1
    );
}

#[test]
fn counts_missing_locomotive_catalog_context_frontier() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState::default(),
        metadata: BTreeMap::new(),
        companies: Vec::new(),
        selected_company_id: None,
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: Some(RuntimePackedEventCollectionSummary {
            source_kind: "packed-event-runtime-collection".to_string(),
            mechanism_family: "classic-save-rehydrate-v1".to_string(),
            mechanism_confidence: "grounded".to_string(),
            container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
            packed_state_version: 0x3e9,
            packed_state_version_hex: "0x000003e9".to_string(),
            live_id_bound: 1,
            live_record_count: 1,
            live_entry_ids: vec![1],
            decoded_record_count: 1,
            imported_runtime_record_count: 0,
            records: vec![RuntimePackedEventRecordSummary {
                record_index: 0,
                live_entry_id: 1,
                payload_offset: Some(0x7202),
                payload_len: Some(96),
                decode_status: "parity_only".to_string(),
                payload_family: "real_packed_v1".to_string(),
                trigger_kind: Some(7),
                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![1, 0, 0, 0],
                grouped_effect_rows: Vec::new(),
                grouped_company_targets: Vec::new(),
                decoded_conditions: Vec::new(),
                decoded_actions: Vec::new(),
                executable_import_ready: false,
                import_outcome: Some("blocked_missing_locomotive_catalog_context".to_string()),
                notes: Vec::new(),
            }],
        }),
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState::default(),
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(
        summary.packed_event_blocked_missing_locomotive_catalog_context_count,
        1
    );
}

#[test]
fn counts_shell_owned_descriptor_frontier() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState::default(),
        metadata: BTreeMap::new(),
        companies: Vec::new(),
        selected_company_id: None,
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: Some(RuntimePackedEventCollectionSummary {
            source_kind: "packed-event-runtime-collection".to_string(),
            mechanism_family: "classic-save-rehydrate-v1".to_string(),
            mechanism_confidence: "grounded".to_string(),
            container_profile_family: Some("rt3-classic-save-container-v1".to_string()),
            packed_state_version: 0x3e9,
            packed_state_version_hex: "0x000003e9".to_string(),
            live_id_bound: 1,
            live_record_count: 1,
            live_entry_ids: vec![1],
            decoded_record_count: 1,
            imported_runtime_record_count: 0,
            records: vec![RuntimePackedEventRecordSummary {
                record_index: 0,
                live_entry_id: 1,
                payload_offset: Some(0),
                payload_len: Some(0),
                decode_status: "parity_only".to_string(),
                payload_family: "real_packed_v1".to_string(),
                trigger_kind: Some(7),
                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![1, 0, 0, 0],
                grouped_effect_rows: Vec::new(),
                grouped_company_targets: Vec::new(),
                decoded_conditions: Vec::new(),
                decoded_actions: Vec::new(),
                executable_import_ready: false,
                import_outcome: Some("blocked_shell_owned_descriptor".to_string()),
                notes: Vec::new(),
            }],
        }),
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState::default(),
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(summary.packed_event_blocked_shell_owned_descriptor_count, 1);
}

#[test]
fn summarizes_selected_company_market_state() {
    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1830,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            auto_show_grade_during_track_lay_raw_u8: Some(2),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![RuntimeCompany {
            company_id: 1,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            active: true,
            available_track_laying_capacity: None,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
        }],
        selected_company_id: Some(1),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: vec![crate::state::RuntimeChairmanProfile {
            profile_id: 1,
            name: "Chairman One".to_string(),
            active: true,
            current_cash: 0,
            linked_company_id: Some(1),
            company_holdings: std::collections::BTreeMap::from([(1, 5_000)]),
            holdings_value_total: 0,
            net_worth_total: 0,
            purchasing_power_total: 0,
        }],
        selected_chairman_profile_id: Some(1),
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                1,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 20_000,
                    bond_count: 2,
                    live_bond_slots: Vec::new(),
                    highest_coupon_live_bond_principal: Some(350_000),
                    largest_live_bond_principal: Some(500_000),
                    mutable_support_scalar_raw_u32: 0x3f800000,
                    young_company_support_scalar_raw_u32: 0x42340000,
                    support_progress_word: 12,
                    recent_per_share_cache_absolute_counter: 42,
                    recent_per_share_cached_value_bits: 14.5f64.to_bits(),
                    recent_per_share_subscore_raw_u32: 0x420c0000,
                    cached_share_price_raw_u32: 0x42200000,
                    chairman_salary_baseline: 24,
                    chairman_salary_current: 30,
                    chairman_bonus_year: 1842,
                    chairman_bonus_amount: 750,
                    founding_year: 1831,
                    last_bankruptcy_year: 0,
                    last_dividend_year: 1841,
                    current_issue_calendar_word: 5,
                    current_issue_calendar_word_2: 6,
                    prior_issue_calendar_word: 4,
                    prior_issue_calendar_word_2: 5,
                    city_connection_latch: true,
                    linked_transit_latch: false,
                    linked_transit_route_anchor_entry_id: Some(77),
                    linked_transit_route_anchor_fallback_counts: vec![3, 5, 8],
                    stat_band_root_0cfb_candidates: vec![
                        crate::state::RuntimeCompanyStatBandCandidate {
                            label: "stat_band_0cfb_word_1".to_string(),
                            relative_offset: 0x0cfb,
                            relative_offset_hex: "0xcfb".to_string(),
                            raw_u32: 1,
                            raw_u32_hex: "0x00000001".to_string(),
                            value_i32: 1,
                            value_f32_text: "0.000000".to_string(),
                        },
                        crate::state::RuntimeCompanyStatBandCandidate {
                            label: "stat_band_0cfb_word_2".to_string(),
                            relative_offset: 0x0cff,
                            relative_offset_hex: "0xcff".to_string(),
                            raw_u32: 2,
                            raw_u32_hex: "0x00000002".to_string(),
                            value_i32: 2,
                            value_f32_text: "0.000000".to_string(),
                        },
                    ],
                    stat_band_root_0d7f_candidates: vec![
                        crate::state::RuntimeCompanyStatBandCandidate {
                            label: "stat_band_0d7f_word_1".to_string(),
                            relative_offset: 0x0d7f,
                            relative_offset_hex: "0xd7f".to_string(),
                            raw_u32: 3,
                            raw_u32_hex: "0x00000003".to_string(),
                            value_i32: 3,
                            value_f32_text: "0.000000".to_string(),
                        },
                    ],
                    stat_band_root_1c47_candidates: vec![
                        crate::state::RuntimeCompanyStatBandCandidate {
                            label: "stat_band_1c47_word_1".to_string(),
                            relative_offset: 0x1c47,
                            relative_offset_hex: "0x1c47".trim_start_matches("0x").to_string(),
                            raw_u32: 4,
                            raw_u32_hex: "0x00000004".to_string(),
                            value_i32: 4,
                            value_f32_text: "0.000000".to_string(),
                        },
                    ],
                    year_stat_family_qword_bits: Vec::new(),
                    special_stat_family_232a_qword_bits: Vec::new(),
                    issue_opinion_terms_raw_i32: Vec::new(),
                    direct_control_transfer_float_fields_raw_u32: BTreeMap::new(),
                    direct_control_transfer_int_fields_raw_u32: BTreeMap::new(),
                },
            )]),
            company_periodic_side_latch_state: BTreeMap::from([(
                1,
                crate::state::RuntimeCompanyPeriodicSideLatchState {
                    preferred_locomotive_engine_type_raw_u8: Some(2),
                    city_connection_latch: true,
                    linked_transit_latch: false,
                },
            )]),
            ..RuntimeServiceState::default()
        },
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(summary.company_market_state_owner_count, 1);
    assert_eq!(summary.selected_company_outstanding_shares, Some(20_000));
    assert_eq!(summary.selected_company_bond_count, Some(2));
    assert_eq!(
        summary.selected_company_largest_live_bond_principal,
        Some(500_000)
    );
    assert_eq!(
        summary.selected_company_highest_coupon_live_bond_principal,
        Some(350_000)
    );
    assert_eq!(summary.selected_company_assigned_share_pool, Some(5_000));
    assert_eq!(summary.selected_company_unassigned_share_pool, Some(15_000));
    assert_eq!(summary.selected_company_cached_share_price, Some(40));
    assert_eq!(
        summary.selected_company_cached_share_price_value_f32_text,
        Some("40.000000".to_string())
    );
    assert_eq!(
        summary.selected_company_recent_per_share_cache_absolute_counter,
        Some(42)
    );
    assert_eq!(
        summary.selected_company_recent_per_share_cached_value_f64_text,
        Some("14.500000".to_string())
    );
    assert_eq!(
        summary.selected_company_recent_per_share_subscore_value_f32_text,
        Some("35.000000".to_string())
    );
    assert_eq!(
        summary.selected_company_mutable_support_scalar_value_f32_text,
        Some("1.000000".to_string())
    );
    assert_eq!(summary.selected_company_stat_band_root_0cfb_count, 2);
    assert_eq!(summary.selected_company_stat_band_root_0d7f_count, 1);
    assert_eq!(summary.selected_company_stat_band_root_1c47_count, 1);
    assert_eq!(summary.selected_company_last_dividend_year, Some(1841));
    assert_eq!(summary.selected_company_years_since_founding, None);
    assert_eq!(summary.selected_company_years_since_last_bankruptcy, None);
    assert_eq!(summary.selected_company_years_since_last_dividend, None);
    assert_eq!(
        summary.selected_company_periodic_side_latch_preferred_locomotive_engine_type_raw_u8,
        Some(2)
    );
    assert_eq!(
        summary.selected_company_periodic_side_latch_city_connection_latch,
        Some(true)
    );
    assert_eq!(
        summary.selected_company_periodic_side_latch_linked_transit_latch,
        Some(false)
    );
    assert_eq!(
        summary.selected_company_linked_transit_route_anchor_entry_id,
        Some(77)
    );
    assert_eq!(
        summary.selected_company_linked_transit_route_anchor_fallback_counts,
        vec![3, 5, 8]
    );
    assert_eq!(
        summary.selected_company_periodic_service_base_route_preference_raw_u8,
        Some(2)
    );
    assert_eq!(
        summary.selected_company_periodic_service_effective_route_preference_raw_u8,
        Some(2)
    );
    assert_eq!(
        summary.selected_company_periodic_service_electric_route_preference_override_active,
        Some(true)
    );
    assert_eq!(
        summary.selected_company_periodic_service_route_quality_multiplier_basis_points,
        Some(180)
    );
    assert_eq!(
        summary.active_periodic_route_preference_override_company_id,
        None
    );
    assert_eq!(
        summary.last_periodic_route_preference_override_company_id,
        None
    );
    assert_eq!(summary.periodic_route_preference_override_apply_count, 0);
    assert_eq!(summary.periodic_route_preference_override_restore_count, 0);
    assert_eq!(summary.selected_company_chairman_bonus_year, Some(1842));
    assert_eq!(summary.selected_company_chairman_bonus_amount, Some(750));
}

#[test]
fn summarizes_selected_company_creditor_pressure_branch_state() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
        let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
        bits[index] = value.to_bits();
    };
    let write_prior_year_value =
        |bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
            let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
            bits[index] = value.to_bits();
        };
    write_current_value(&mut year_stat_family_qword_bits, 0x09, -50_000.0);
    write_current_value(&mut year_stat_family_qword_bits, 0x0d, -700_000.0);
    write_current_value(&mut year_stat_family_qword_bits, 0x12, 0.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 100_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 90_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 3, 80_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -115_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -110_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 3, -110_000.0);

    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            partial_year_progress_raw_u8: Some(0x0c),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![RuntimeCompany {
            company_id: 7,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            active: true,
            available_track_laying_capacity: None,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
        }],
        selected_company_id: Some(7),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                7,
                crate::state::RuntimeCompanyMarketState {
                    founding_year: 1841,
                    last_bankruptcy_year: 1832,
                    cached_share_price_raw_u32: 25.0f32.to_bits(),
                    year_stat_family_qword_bits,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..RuntimeServiceState::default()
        },
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(
        summary.selected_company_creditor_pressure_recent_bad_net_profit_year_count,
        Some(3)
    );
    assert_eq!(
        summary.selected_company_creditor_pressure_recent_peak_revenue,
        Some(100_000)
    );
    assert_eq!(
        summary.selected_company_creditor_pressure_recent_three_year_net_profit_total,
        Some(-65_000)
    );
    assert_eq!(
        summary.selected_company_creditor_pressure_cash_floor,
        Some(-600_000)
    );
    assert_eq!(
        summary.selected_company_creditor_pressure_cash_plus_slot_12_total,
        Some(-700_000)
    );
    assert_eq!(
        summary.selected_company_creditor_pressure_share_price_floor,
        Some(20)
    );
    assert_eq!(
        summary.selected_company_creditor_pressure_share_price_scalar,
        Some(25)
    );
    assert_eq!(
        summary.selected_company_creditor_pressure_current_fuel_cost,
        Some(-50_000)
    );
    assert_eq!(
        summary.selected_company_creditor_pressure_current_fuel_cost_floor,
        Some(-48_000)
    );
    assert_eq!(
        summary.selected_company_creditor_pressure_eligible_for_bankruptcy_branch,
        Some(true)
    );
}

#[test]
fn summarizes_selected_company_deep_distress_fallback_state() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
        let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
        bits[index] = value.to_bits();
    };
    let write_prior_year_value =
        |bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
            let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
            bits[index] = value.to_bits();
        };
    write_current_value(&mut year_stat_family_qword_bits, 0x0d, -350_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 10_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 15_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 3, 12_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -35_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -38_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 3, -33_000.0);

    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![RuntimeCompany {
            company_id: 9,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            active: true,
            available_track_laying_capacity: None,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
        }],
        selected_company_id: Some(9),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                9,
                crate::state::RuntimeCompanyMarketState {
                    founding_year: 1841,
                    last_bankruptcy_year: 1840,
                    year_stat_family_qword_bits,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..RuntimeServiceState::default()
        },
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(
        summary.selected_company_deep_distress_current_cash,
        Some(-350_000)
    );
    assert_eq!(
        summary.selected_company_deep_distress_recent_first_three_net_profit_years,
        vec![-25_000, -23_000, -21_000]
    );
    assert_eq!(
        summary.selected_company_deep_distress_cash_floor,
        Some(-300_000)
    );
    assert_eq!(
        summary.selected_company_deep_distress_net_profit_floor,
        Some(-20_000)
    );
    assert_eq!(
        summary.selected_company_deep_distress_eligible_for_bankruptcy_fallback,
        Some(true)
    );
}

#[test]
fn summarizes_selected_company_stock_repurchase_state() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
        let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
        bits[index] = value.to_bits();
    };
    write_current_value(&mut year_stat_family_qword_bits, 0x0d, 1_600_000.0);

    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            partial_year_progress_raw_u8: Some(0x0c),
            stock_issue_and_buyback_policy_raw_u8: Some(0),
            stock_issue_and_buyback_allowed: Some(true),
            building_density_growth_setting_raw_u32: Some(1),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![RuntimeCompany {
            company_id: 12,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            active: true,
            available_track_laying_capacity: None,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            linked_chairman_profile_id: Some(3),
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
        }],
        selected_company_id: Some(12),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: vec![crate::state::RuntimeChairmanProfile {
            profile_id: 3,
            name: "Jay".to_string(),
            active: true,
            current_cash: 200,
            linked_company_id: Some(12),
            company_holdings: BTreeMap::from([(12, 14_500)]),
            holdings_value_total: 0,
            net_worth_total: 0,
            purchasing_power_total: 0,
        }],
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: Vec::new().into_iter().collect(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                12,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 20_000,
                    cached_share_price_raw_u32: 20.0f32.to_bits(),
                    founding_year: 1835,
                    city_connection_latch: true,
                    year_stat_family_qword_bits,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            chairman_personality_raw_u8: BTreeMap::from([(3, 20)]),
            ..RuntimeServiceState::default()
        },
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(
        summary.world_restore_building_density_growth_setting_raw_u32,
        Some(1)
    );
    assert_eq!(
        summary.selected_company_stock_repurchase_building_density_growth_setting,
        Some(1)
    );
    assert_eq!(
        summary.selected_company_stock_repurchase_linked_chairman_personality_raw_u8,
        Some(20)
    );
    assert_eq!(
        summary.selected_company_stock_repurchase_batch_size,
        Some(1_000)
    );
    assert_eq!(
        summary.selected_company_stock_repurchase_factor_basis_points,
        Some(432)
    );
    assert_eq!(
        summary.selected_company_stock_repurchase_current_cash,
        Some(1_600_000)
    );
    assert_eq!(
        summary.selected_company_stock_repurchase_stock_value_gate_cash_floor,
        Some(3_456_000)
    );
    assert_eq!(
        summary.selected_company_stock_repurchase_support_adjusted_share_price_scalar,
        Some(20)
    );
    assert_eq!(
        summary.selected_company_stock_repurchase_affordability_cash_floor,
        Some(103_680)
    );
    assert_eq!(
        summary.selected_company_stock_repurchase_unassigned_share_pool,
        Some(5_500)
    );
    assert_eq!(
        summary.selected_company_stock_repurchase_eligible_for_single_batch,
        Some(false)
    );
}

#[test]
fn summarizes_selected_company_annual_bond_policy_state() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    year_stat_family_qword_bits[(RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH
        * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize] = (-400_000.0f64).to_bits();

    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            partial_year_progress_raw_u8: Some(0x0c),
            bond_issue_and_repayment_policy_raw_u8: Some(0),
            bond_issue_and_repayment_allowed: Some(true),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![RuntimeCompany {
            company_id: 11,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            active: true,
            available_track_laying_capacity: None,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
        }],
        selected_company_id: Some(11),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: Vec::new(),
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: Vec::new().into_iter().collect(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                11,
                crate::state::RuntimeCompanyMarketState {
                    bond_count: 2,
                    linked_transit_latch: true,
                    live_bond_slots: vec![
                        crate::state::RuntimeCompanyBondSlot {
                            slot_index: 0,
                            principal: 200_000,
                            maturity_year: 0,
                            coupon_rate_raw_u32: 0.09f32.to_bits(),
                        },
                        crate::state::RuntimeCompanyBondSlot {
                            slot_index: 1,
                            principal: 150_000,
                            maturity_year: 0,
                            coupon_rate_raw_u32: 0.08f32.to_bits(),
                        },
                    ],
                    year_stat_family_qword_bits,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..RuntimeServiceState::default()
        },
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(
        summary.selected_company_annual_bond_linked_transit_latch,
        Some(true)
    );
    assert_eq!(
        summary.selected_company_annual_bond_live_bond_count,
        Some(2)
    );
    assert_eq!(
        summary.selected_company_annual_bond_live_bond_principal_total,
        Some(350_000)
    );
    assert_eq!(
        summary.selected_company_annual_bond_matured_live_bond_count,
        Some(0)
    );
    assert_eq!(
        summary.selected_company_annual_bond_matured_live_bond_principal_total,
        Some(0)
    );
    assert_eq!(
        summary.selected_company_annual_bond_next_live_bond_maturity_year,
        None
    );
    assert_eq!(
        summary.selected_company_annual_bond_live_bond_coupon_burden_total,
        Some(30_000)
    );
    assert_eq!(
        summary.selected_company_annual_bond_current_cash,
        Some(-400_000)
    );
    assert_eq!(
        summary.selected_company_annual_bond_cash_after_full_repayment,
        Some(-750_000)
    );
    assert_eq!(
        summary.selected_company_annual_bond_issue_cash_floor,
        Some(-30_000)
    );
    assert_eq!(
        summary.selected_company_annual_bond_issue_principal_step,
        Some(500_000)
    );
    assert_eq!(
        summary.selected_company_annual_bond_proposed_issue_bond_count,
        Some(2)
    );
    assert_eq!(
        summary.selected_company_annual_bond_proposed_issue_total_principal,
        Some(1_000_000)
    );
    assert_eq!(
        summary.selected_company_annual_bond_proposed_issue_years_to_maturity,
        Some(30)
    );
    assert_eq!(
        summary.selected_company_annual_bond_eligible_for_issue_branch,
        Some(true)
    );
}

#[test]
fn summarizes_selected_company_stock_issue_state() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    year_stat_family_qword_bits[(RUNTIME_COMPANY_STAT_SLOT_CURRENT_CASH
        * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize] = 250_000.0f64.to_bits();

    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: RuntimeSaveProfileState::default(),
        world_restore: RuntimeWorldRestoreState {
            partial_year_progress_raw_u8: Some(0x0c),
            stock_issue_and_buyback_policy_raw_u8: Some(0),
            stock_issue_and_buyback_allowed: Some(true),
            bond_issue_and_repayment_policy_raw_u8: Some(0),
            bond_issue_and_repayment_allowed: Some(true),
            issue_37_value: Some(2),
            issue_37_multiplier_raw_u32: Some(1.0f32.to_bits()),
            issue_37_multiplier_value_f32_text: Some("1.000000".to_string()),
            absolute_counter_raw_u32: Some(885_911_040),
            ..RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![RuntimeCompany {
            company_id: 14,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            active: true,
            available_track_laying_capacity: None,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            linked_chairman_profile_id: Some(8),
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
            track_piece_counts: RuntimeTrackPieceCounts::default(),
        }],
        selected_company_id: Some(14),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: vec![crate::state::RuntimeChairmanProfile {
            profile_id: 8,
            name: "Taylor".to_string(),
            active: true,
            current_cash: 200,
            linked_company_id: Some(14),
            company_holdings: BTreeMap::from([(14, 14_000)]),
            holdings_value_total: 0,
            net_worth_total: 0,
            purchasing_power_total: 0,
        }],
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: Vec::new().into_iter().collect(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: RuntimeServiceState {
            world_issue_opinion_base_terms_raw_i32: vec![0; 0x3b],
            chairman_personality_raw_u8: BTreeMap::from([(8, 20)]),
            annual_finance_last_actions: BTreeMap::from([(
                14,
                crate::state::RuntimeCompanyAnnualFinancePolicyAction::StockIssue,
            )]),
            annual_finance_last_news_family_candidates: BTreeMap::from([(14, "4053".to_string())]),
            annual_finance_last_news_events: vec![RuntimeAnnualFinanceNewsEvent {
                company_id: 14,
                selector_label: "4053".to_string(),
                action_label: "stock_issue".to_string(),
                retired_principal_total: 0,
                issued_principal_total: 0,
                repurchased_share_count: 0,
                issued_share_count: 4_000,
            }],
            company_market_state: BTreeMap::from([(
                14,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 20_000,
                    bond_count: 2,
                    highest_coupon_live_bond_principal: Some(300_000),
                    current_issue_calendar_word: 0x0101_0725,
                    current_issue_calendar_word_2: 0x0001_0001,
                    founding_year: 1840,
                    cached_share_price_raw_u32: 35.0f32.to_bits(),
                    recent_per_share_cache_absolute_counter: 885_911_040,
                    recent_per_share_cached_value_bits: 34.0f64.to_bits(),
                    live_bond_slots: vec![
                        crate::state::RuntimeCompanyBondSlot {
                            slot_index: 0,
                            principal: 300_000,
                            maturity_year: 0,
                            coupon_rate_raw_u32: 0.11f32.to_bits(),
                        },
                        crate::state::RuntimeCompanyBondSlot {
                            slot_index: 1,
                            principal: 200_000,
                            maturity_year: 0,
                            coupon_rate_raw_u32: 0.07f32.to_bits(),
                        },
                    ],
                    direct_control_transfer_float_fields_raw_u32: BTreeMap::from([(
                        0x32f,
                        30.0f32.to_bits(),
                    )]),
                    year_stat_family_qword_bits,
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..RuntimeServiceState::default()
        },
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(
        summary.selected_company_stock_issue_live_bond_count,
        Some(2)
    );
    assert_eq!(
        summary.selected_company_stock_issue_initial_batch_size,
        Some(2_000)
    );
    assert_eq!(
        summary.selected_company_stock_issue_trimmed_batch_size,
        Some(2_000)
    );
    assert_eq!(
        summary.selected_company_stock_issue_share_pressure_basis_points,
        Some(-1_000)
    );
    assert_eq!(
        summary.selected_company_stock_issue_pressured_share_price_scalar,
        Some(35)
    );
    assert_eq!(
        summary.selected_company_stock_issue_pressured_proceeds,
        Some(70_000)
    );
    assert_eq!(
        summary.selected_company_stock_issue_book_value_per_share_floor_applied,
        Some(30)
    );
    assert_eq!(
        summary.selected_company_stock_issue_price_to_book_ratio_basis_points,
        Some(11_667)
    );
    assert_eq!(
        summary.selected_company_stock_issue_current_cash,
        Some(250_000)
    );
    assert_eq!(
        summary.selected_company_stock_issue_highest_coupon_live_bond_principal,
        Some(300_000)
    );
    assert_eq!(
        summary.selected_company_stock_issue_highest_coupon_live_bond_rate_basis_points,
        Some(1_100)
    );
    assert_eq!(
        summary.selected_company_stock_issue_current_issue_age_absolute_counter_delta,
        Some(967_680)
    );
    assert_eq!(
        summary.selected_company_stock_issue_current_issue_cooldown_floor,
        Some(483_840)
    );
    assert_eq!(
        summary.selected_company_stock_issue_minimum_price_to_book_ratio_basis_points,
        Some(8_000)
    );
    assert_eq!(
        summary.selected_company_stock_issue_passes_share_price_floor,
        Some(true)
    );
    assert_eq!(
        summary.selected_company_stock_issue_passes_proceeds_floor,
        Some(true)
    );
    assert_eq!(
        summary.selected_company_stock_issue_passes_cash_gate,
        Some(true)
    );
    assert_eq!(
        summary.selected_company_stock_issue_passes_issue_cooldown_gate,
        Some(true)
    );
    assert_eq!(
        summary.selected_company_stock_issue_passes_coupon_price_to_book_gate,
        Some(true)
    );
    assert_eq!(
        summary.selected_company_stock_issue_eligible_for_double_tranche,
        Some(true)
    );
    assert_eq!(
        summary
            .selected_company_annual_finance_news_family_candidate
            .as_deref(),
        Some("4053")
    );
    assert_eq!(
        summary
            .selected_company_annual_finance_last_news_selector
            .as_deref(),
        Some("4053")
    );
    assert_eq!(summary.annual_finance_last_news_event_count, 1);
}

#[test]
fn summarizes_selected_company_annual_dividend_policy_state() {
    let mut year_stat_family_qword_bits = vec![
        0u64;
        ((RUNTIME_COMPANY_STAT_SLOT_COUNT + 2) * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN)
            as usize
    ];
    let write_current_value = |bits: &mut Vec<u64>, slot_id: u32, value: f64| {
        let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN) as usize;
        bits[index] = value.to_bits();
    };
    let write_prior_year_value =
        |bits: &mut Vec<u64>, slot_id: u32, year_delta: u32, value: f64| {
            let index = (slot_id * RUNTIME_COMPANY_YEAR_STAT_FAMILY_SPAN + year_delta) as usize;
            bits[index] = value.to_bits();
        };
    write_current_value(&mut year_stat_family_qword_bits, 0x0d, 300_000.0);
    write_current_value(&mut year_stat_family_qword_bits, 0x01, 300_000.0);
    write_current_value(&mut year_stat_family_qword_bits, 0x09, -180_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 1, 280_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 1, -190_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x01, 2, 260_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x09, 2, -200_000.0);
    write_prior_year_value(&mut year_stat_family_qword_bits, 0x1c, 1, 5.0);

    let state = RuntimeState {
        calendar: CalendarPoint {
            year: 1845,
            month_slot: 0,
            phase_slot: 0,
            tick_slot: 0,
        },
        world_flags: BTreeMap::new(),
        save_profile: crate::state::RuntimeSaveProfileState::default(),
        world_restore: crate::state::RuntimeWorldRestoreState {
            packed_year_word_raw_u16: Some(1845),
            partial_year_progress_raw_u8: Some(0x0c),
            dividend_policy_raw_u8: Some(0),
            dividend_adjustment_allowed: Some(true),
            stock_issue_and_buyback_policy_raw_u8: Some(0),
            stock_issue_and_buyback_allowed: Some(true),
            bond_issue_and_repayment_policy_raw_u8: Some(0),
            bond_issue_and_repayment_allowed: Some(true),
            bankruptcy_policy_raw_u8: Some(0),
            bankruptcy_allowed: Some(true),
            building_density_growth_setting_raw_u32: Some(1),
            ..crate::state::RuntimeWorldRestoreState::default()
        },
        metadata: BTreeMap::new(),
        companies: vec![crate::state::RuntimeCompany {
            company_id: 15,
            current_cash: 0,
            debt: 0,
            credit_rating_score: None,
            prime_rate: None,
            active: true,
            available_track_laying_capacity: None,
            controller_kind: crate::state::RuntimeCompanyControllerKind::Unknown,
            linked_chairman_profile_id: None,
            book_value_per_share: 0,
            investor_confidence: 0,
            management_attitude: 0,
            takeover_cooldown_year: None,
            merger_cooldown_year: None,
            track_piece_counts: crate::state::RuntimeTrackPieceCounts::default(),
        }],
        selected_company_id: Some(15),
        players: Vec::new(),
        selected_player_id: None,
        chairman_profiles: vec![crate::state::RuntimeChairmanProfile {
            profile_id: 3,
            name: "Chairman Three".to_string(),
            active: true,
            current_cash: 0,
            linked_company_id: Some(15),
            company_holdings: BTreeMap::from([(15, 9_500)]),
            holdings_value_total: 0,
            net_worth_total: 0,
            purchasing_power_total: 0,
        }],
        selected_chairman_profile_id: None,
        trains: Vec::new(),
        locomotive_catalog: Vec::new(),
        cargo_catalog: Vec::new(),
        territories: Vec::new(),
        company_territory_track_piece_counts: Vec::new(),
        company_territory_access: Vec::new(),
        packed_event_collection: None,
        event_runtime_records: Vec::new(),
        candidate_availability: BTreeMap::new(),
        named_locomotive_availability: BTreeMap::new(),
        named_locomotive_cost: BTreeMap::new(),
        all_cargo_price_override: None,
        named_cargo_price_overrides: BTreeMap::new(),
        all_cargo_production_override: None,
        factory_cargo_production_override: None,
        farm_mine_cargo_production_override: None,
        named_cargo_production_overrides: BTreeMap::new(),
        cargo_production_overrides: BTreeMap::new(),
        world_runtime_variables: BTreeMap::new(),
        company_runtime_variables: BTreeMap::new(),
        player_runtime_variables: BTreeMap::new(),
        territory_runtime_variables: BTreeMap::new(),
        world_scalar_overrides: BTreeMap::new(),
        special_conditions: BTreeMap::new(),
        service_state: crate::state::RuntimeServiceState {
            company_market_state: BTreeMap::from([(
                15,
                crate::state::RuntimeCompanyMarketState {
                    outstanding_shares: 10_000,
                    founding_year: 1840,
                    last_dividend_year: 1844,
                    year_stat_family_qword_bits,
                    direct_control_transfer_float_fields_raw_u32: BTreeMap::from([(
                        0x33f,
                        0.4f32.to_bits(),
                    )]),
                    ..crate::state::RuntimeCompanyMarketState::default()
                },
            )]),
            ..crate::state::RuntimeServiceState::default()
        },
    };

    let summary = RuntimeSummary::from_state(&state);
    assert_eq!(
        summary.selected_company_dividend_weighted_recent_net_profit_total,
        Some(600_000)
    );
    assert_eq!(
        summary.selected_company_dividend_weighted_recent_net_profit_average,
        Some(100_000)
    );
    assert_eq!(
        summary.selected_company_dividend_current_cash,
        Some(300_000)
    );
    assert_eq!(
        summary.selected_company_dividend_tiny_unassigned_share_cash_supplement_branch,
        Some(true)
    );
    assert_eq!(
        summary.selected_company_dividend_tentative_target_per_share_tenths,
        Some(133)
    );
    assert_eq!(
        summary.selected_company_dividend_current_per_share_tenths,
        Some(4)
    );
    assert_eq!(
        summary.selected_company_dividend_growth_adjusted_current_per_share_tenths,
        Some(3)
    );
    assert_eq!(
        summary.selected_company_dividend_board_approved_ceiling_tenths,
        Some(18)
    );
    assert_eq!(
        summary.selected_company_dividend_proposed_per_share_tenths,
        Some(18)
    );
    assert_eq!(
        summary.selected_company_dividend_eligible_for_adjustment_branch,
        Some(true)
    );
    assert_eq!(
        summary
            .selected_company_annual_finance_policy_action
            .as_deref(),
        Some("dividend_adjustment")
    );
    assert_eq!(
        summary.selected_company_annual_finance_policy_dividend_adjustment_eligible,
        Some(true)
    );
}
