use super::*;

#[test]
fn decodes_real_special_condition_descriptor_from_checked_in_metadata() {
    let grouped_row = build_real_grouped_effect_row(RealGroupedEffectRowSpec {
        descriptor_id: 108,
        opcode: 3,
        raw_scalar_value: 1,
        value_byte_0x09: 0,
        value_dword_0x0d: 0,
        value_byte_0x11: 0,
        value_byte_0x12: 0,
        value_word_0x14: 0,
        value_word_0x16: 0,
        locomotive_name: None,
    });
    let group0_rows = vec![grouped_row];
    let record_body = build_real_event_record(
        [b"World", b"", b"", b"", b"", b""],
        Some(RealCompactControlSpec {
            mode_byte_0x7ef: 7,
            primary_selector_0x7f0: 0,
            grouped_mode_0x7f4: 2,
            one_shot_header_0x7f5: 0,
            modifier_flag_0x7f9: 0,
            modifier_flag_0x7fa: 0,
            grouped_target_scope_ordinals_0x7fb: [0, 0, 0, 0],
            grouped_scope_checkboxes_0x7ff: [1, 0, 0, 0],
            summary_toggle_0x800: 1,
            grouped_territory_selectors_0x80f: [-1, -1, -1, -1],
        }),
        &[],
        [&group0_rows, &[], &[], &[]],
    );

    let mut bytes = Vec::new();
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_METADATA_TAG.to_le_bytes());
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION.to_le_bytes());
    let header_words = [1u32, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for word in header_words {
        bytes.extend_from_slice(&word.to_le_bytes());
    }
    bytes.extend_from_slice(&[0x00, 0x00]);
    bytes.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd]);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_RECORDS_TAG.to_le_bytes());
    bytes.extend_from_slice(&record_body);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_CLOSE_TAG.to_le_bytes());

    let report = inspect_smp_bytes(&bytes);
    let summary = report
        .event_runtime_collection_summary
        .as_ref()
        .expect("event runtime collection summary should parse");

    assert_eq!(
        summary.records[0].grouped_effect_rows[0]
            .descriptor_label
            .as_deref(),
        Some("Use Wartime Cargos")
    );
    assert_eq!(
        summary.records[0].grouped_effect_rows[0]
            .parameter_family
            .as_deref(),
        Some("special_condition_scalar")
    );
    assert_eq!(
        summary.records[0].decoded_actions,
        vec![RuntimeEffect::SetSpecialCondition {
            label: "Use Wartime Cargos".to_string(),
            value: 1,
        }]
    );
    assert!(summary.records[0].executable_import_ready);
}

#[test]
fn decodes_real_candidate_availability_descriptor_from_checked_in_metadata() {
    let grouped_row = build_real_grouped_effect_row(RealGroupedEffectRowSpec {
        descriptor_id: 109,
        opcode: 3,
        raw_scalar_value: 1,
        value_byte_0x09: 0,
        value_dword_0x0d: 0,
        value_byte_0x11: 0,
        value_byte_0x12: 0,
        value_word_0x14: 0,
        value_word_0x16: 0,
        locomotive_name: None,
    });
    let group0_rows = vec![grouped_row];
    let record_body = build_real_event_record(
        [b"World", b"", b"", b"", b"", b""],
        Some(RealCompactControlSpec {
            mode_byte_0x7ef: 7,
            primary_selector_0x7f0: 0,
            grouped_mode_0x7f4: 2,
            one_shot_header_0x7f5: 0,
            modifier_flag_0x7f9: 0,
            modifier_flag_0x7fa: 0,
            grouped_target_scope_ordinals_0x7fb: [0, 0, 0, 0],
            grouped_scope_checkboxes_0x7ff: [1, 0, 0, 0],
            summary_toggle_0x800: 1,
            grouped_territory_selectors_0x80f: [-1, -1, -1, -1],
        }),
        &[],
        [&group0_rows, &[], &[], &[]],
    );

    let mut bytes = Vec::new();
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_METADATA_TAG.to_le_bytes());
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION.to_le_bytes());
    let header_words = [1u32, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for word in header_words {
        bytes.extend_from_slice(&word.to_le_bytes());
    }
    bytes.extend_from_slice(&[0x00, 0x00]);
    bytes.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd]);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_RECORDS_TAG.to_le_bytes());
    bytes.extend_from_slice(&record_body);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_CLOSE_TAG.to_le_bytes());

    let report = inspect_smp_bytes(&bytes);
    let summary = report
        .event_runtime_collection_summary
        .as_ref()
        .expect("event runtime collection summary should parse");

    assert_eq!(
        summary.records[0].grouped_effect_rows[0]
            .descriptor_label
            .as_deref(),
        Some("Turbo Diesel Availability")
    );
    assert_eq!(
        summary.records[0].grouped_effect_rows[0]
            .parameter_family
            .as_deref(),
        Some("candidate_availability_scalar")
    );
    assert_eq!(
        summary.records[0].decoded_actions,
        vec![RuntimeEffect::SetCandidateAvailability {
            name: "Turbo Diesel".to_string(),
            value: 1,
        }]
    );
    assert!(summary.records[0].executable_import_ready);
}

#[test]
fn decodes_real_special_condition_threshold_from_checked_in_world_condition_metadata() {
    let condition_row = build_real_condition_row_with_threshold(3835, 0, 1, None);
    let record_body = build_real_event_record(
        [b"World", b"", b"", b"", b"", b""],
        Some(RealCompactControlSpec {
            mode_byte_0x7ef: 7,
            primary_selector_0x7f0: 0,
            grouped_mode_0x7f4: 2,
            one_shot_header_0x7f5: 0,
            modifier_flag_0x7f9: 0,
            modifier_flag_0x7fa: 0,
            grouped_target_scope_ordinals_0x7fb: [0, 0, 0, 0],
            grouped_scope_checkboxes_0x7ff: [0, 0, 0, 0],
            summary_toggle_0x800: 1,
            grouped_territory_selectors_0x80f: [-1, -1, -1, -1],
        }),
        &[condition_row],
        [&[], &[], &[], &[]],
    );

    let mut bytes = Vec::new();
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_METADATA_TAG.to_le_bytes());
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION.to_le_bytes());
    let header_words = [1u32, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for word in header_words {
        bytes.extend_from_slice(&word.to_le_bytes());
    }
    bytes.extend_from_slice(&[0x00, 0x00]);
    bytes.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd]);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_RECORDS_TAG.to_le_bytes());
    bytes.extend_from_slice(&record_body);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_CLOSE_TAG.to_le_bytes());

    let report = inspect_smp_bytes(&bytes);
    let summary = report
        .event_runtime_collection_summary
        .as_ref()
        .expect("event runtime collection summary should parse");

    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .metric
            .as_deref(),
        Some("Special Condition: Use Wartime Cargos")
    );
    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .semantic_family
            .as_deref(),
        Some("world_state_threshold")
    );
    assert_eq!(
        summary.records[0].decoded_conditions,
        vec![RuntimeCondition::SpecialConditionThreshold {
            label: "Use Wartime Cargos".to_string(),
            comparator: RuntimeConditionComparator::Ge,
            value: 1,
        }]
    );
}

#[test]
fn decodes_real_candidate_availability_threshold_from_checked_in_world_condition_metadata() {
    let condition_row = build_real_condition_row_with_threshold(
        REAL_CANDIDATE_AVAILABILITY_CONDITION_TEMPLATE_ID,
        0,
        2,
        Some("Mogul"),
    );
    let record_body = build_real_event_record(
        [b"World", b"", b"", b"", b"", b""],
        Some(RealCompactControlSpec {
            mode_byte_0x7ef: 7,
            primary_selector_0x7f0: 0,
            grouped_mode_0x7f4: 2,
            one_shot_header_0x7f5: 0,
            modifier_flag_0x7f9: 0,
            modifier_flag_0x7fa: 0,
            grouped_target_scope_ordinals_0x7fb: [0, 0, 0, 0],
            grouped_scope_checkboxes_0x7ff: [0, 0, 0, 0],
            summary_toggle_0x800: 1,
            grouped_territory_selectors_0x80f: [-1, -1, -1, -1],
        }),
        &[condition_row],
        [&[], &[], &[], &[]],
    );

    let mut bytes = Vec::new();
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_METADATA_TAG.to_le_bytes());
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION.to_le_bytes());
    let header_words = [1u32, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for word in header_words {
        bytes.extend_from_slice(&word.to_le_bytes());
    }
    bytes.extend_from_slice(&[0x00, 0x00]);
    bytes.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd]);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_RECORDS_TAG.to_le_bytes());
    bytes.extend_from_slice(&record_body);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_CLOSE_TAG.to_le_bytes());

    let report = inspect_smp_bytes(&bytes);
    let summary = report
        .event_runtime_collection_summary
        .as_ref()
        .expect("event runtime collection summary should parse");

    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .metric
            .as_deref(),
        Some("Candidate Availability: Mogul")
    );
    assert_eq!(
        summary.records[0].decoded_conditions,
        vec![RuntimeCondition::CandidateAvailabilityThreshold {
            name: "Mogul".to_string(),
            comparator: RuntimeConditionComparator::Ge,
            value: 2,
        }]
    );
}

#[test]
fn decodes_real_economic_status_threshold_from_checked_in_world_condition_metadata() {
    let condition_row = build_real_condition_row_with_threshold(2350, 0, 4, None);
    let record_body = build_real_event_record(
        [b"World", b"", b"", b"", b"", b""],
        Some(RealCompactControlSpec {
            mode_byte_0x7ef: 7,
            primary_selector_0x7f0: 0,
            grouped_mode_0x7f4: 2,
            one_shot_header_0x7f5: 0,
            modifier_flag_0x7f9: 0,
            modifier_flag_0x7fa: 0,
            grouped_target_scope_ordinals_0x7fb: [0, 0, 0, 0],
            grouped_scope_checkboxes_0x7ff: [0, 0, 0, 0],
            summary_toggle_0x800: 1,
            grouped_territory_selectors_0x80f: [-1, -1, -1, -1],
        }),
        &[condition_row],
        [&[], &[], &[], &[]],
    );

    let mut bytes = Vec::new();
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_METADATA_TAG.to_le_bytes());
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION.to_le_bytes());
    let header_words = [1u32, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for word in header_words {
        bytes.extend_from_slice(&word.to_le_bytes());
    }
    bytes.extend_from_slice(&[0x00, 0x00]);
    bytes.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd]);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_RECORDS_TAG.to_le_bytes());
    bytes.extend_from_slice(&record_body);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_CLOSE_TAG.to_le_bytes());

    let report = inspect_smp_bytes(&bytes);
    let summary = report
        .event_runtime_collection_summary
        .as_ref()
        .expect("event runtime collection summary should parse");

    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .metric
            .as_deref(),
        Some("Economic Status")
    );
    assert_eq!(
        summary.records[0].decoded_conditions,
        vec![RuntimeCondition::EconomicStatusCodeThreshold {
            comparator: RuntimeConditionComparator::Ge,
            value: 4,
        }]
    );
}

#[test]
fn decodes_real_named_locomotive_availability_threshold_from_checked_in_metadata() {
    let condition_row = build_real_condition_row_with_threshold(
        REAL_NAMED_LOCOMOTIVE_AVAILABILITY_CONDITION_ID,
        4,
        42,
        Some("Big Boy"),
    );
    let record_body = build_real_event_record(
        [b"World", b"", b"", b"", b"", b""],
        Some(RealCompactControlSpec {
            mode_byte_0x7ef: 7,
            primary_selector_0x7f0: 0,
            grouped_mode_0x7f4: 2,
            one_shot_header_0x7f5: 0,
            modifier_flag_0x7f9: 0,
            modifier_flag_0x7fa: 0,
            grouped_target_scope_ordinals_0x7fb: [0, 0, 0, 0],
            grouped_scope_checkboxes_0x7ff: [0, 0, 0, 0],
            summary_toggle_0x800: 1,
            grouped_territory_selectors_0x80f: [-1, -1, -1, -1],
        }),
        &[condition_row],
        [&[], &[], &[], &[]],
    );

    let mut bytes = Vec::new();
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_METADATA_TAG.to_le_bytes());
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION.to_le_bytes());
    let header_words = [1u32, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for word in header_words {
        bytes.extend_from_slice(&word.to_le_bytes());
    }
    bytes.extend_from_slice(&[0x00, 0x00]);
    bytes.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd]);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_RECORDS_TAG.to_le_bytes());
    bytes.extend_from_slice(&record_body);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_CLOSE_TAG.to_le_bytes());

    let report = inspect_smp_bytes(&bytes);
    let summary = report
        .event_runtime_collection_summary
        .as_ref()
        .expect("event runtime collection summary should parse");

    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .metric
            .as_deref(),
        Some("Named Locomotive Availability: Big Boy")
    );
    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .semantic_family
            .as_deref(),
        Some("world_scalar_threshold")
    );
    assert_eq!(
        summary.records[0].decoded_conditions,
        vec![RuntimeCondition::NamedLocomotiveAvailabilityThreshold {
            name: "Big Boy".to_string(),
            comparator: RuntimeConditionComparator::Eq,
            value: 42,
        }]
    );
}

#[test]
fn decodes_real_named_locomotive_cost_threshold_from_checked_in_metadata() {
    let condition_row = build_real_condition_row_with_threshold(
        REAL_NAMED_LOCOMOTIVE_COST_CONDITION_ID,
        0,
        250000,
        Some("Locomotive 1"),
    );
    let record_body = build_real_event_record(
        [b"World", b"", b"", b"", b"", b""],
        Some(RealCompactControlSpec {
            mode_byte_0x7ef: 7,
            primary_selector_0x7f0: 0,
            grouped_mode_0x7f4: 2,
            one_shot_header_0x7f5: 0,
            modifier_flag_0x7f9: 0,
            modifier_flag_0x7fa: 0,
            grouped_target_scope_ordinals_0x7fb: [0, 0, 0, 0],
            grouped_scope_checkboxes_0x7ff: [0, 0, 0, 0],
            summary_toggle_0x800: 1,
            grouped_territory_selectors_0x80f: [-1, -1, -1, -1],
        }),
        &[condition_row],
        [&[], &[], &[], &[]],
    );

    let mut bytes = Vec::new();
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_METADATA_TAG.to_le_bytes());
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION.to_le_bytes());
    let header_words = [1u32, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for word in header_words {
        bytes.extend_from_slice(&word.to_le_bytes());
    }
    bytes.extend_from_slice(&[0x00, 0x00]);
    bytes.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd]);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_RECORDS_TAG.to_le_bytes());
    bytes.extend_from_slice(&record_body);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_CLOSE_TAG.to_le_bytes());

    let report = inspect_smp_bytes(&bytes);
    let summary = report
        .event_runtime_collection_summary
        .as_ref()
        .expect("event runtime collection summary should parse");

    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .metric
            .as_deref(),
        Some("Named Locomotive Cost: Locomotive 1")
    );
    assert_eq!(
        summary.records[0].decoded_conditions,
        vec![RuntimeCondition::NamedLocomotiveCostThreshold {
            name: "Locomotive 1".to_string(),
            comparator: RuntimeConditionComparator::Ge,
            value: 250000,
        }]
    );
}

#[test]
fn decodes_real_named_cargo_production_threshold_from_checked_in_metadata() {
    let condition_row = build_real_condition_row_with_threshold(
        REAL_CARGO_PRODUCTION_CONDITION_TEMPLATE_ID,
        4,
        125,
        Some("Cargo Production Slot 1"),
    );
    let record_body = build_real_event_record(
        [b"World", b"", b"", b"", b"", b""],
        Some(RealCompactControlSpec {
            mode_byte_0x7ef: 7,
            primary_selector_0x7f0: 0,
            grouped_mode_0x7f4: 2,
            one_shot_header_0x7f5: 0,
            modifier_flag_0x7f9: 0,
            modifier_flag_0x7fa: 0,
            grouped_target_scope_ordinals_0x7fb: [0, 0, 0, 0],
            grouped_scope_checkboxes_0x7ff: [0, 0, 0, 0],
            summary_toggle_0x800: 1,
            grouped_territory_selectors_0x80f: [-1, -1, -1, -1],
        }),
        &[condition_row],
        [&[], &[], &[], &[]],
    );

    let mut bytes = Vec::new();
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_METADATA_TAG.to_le_bytes());
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION.to_le_bytes());
    let header_words = [1u32, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for word in header_words {
        bytes.extend_from_slice(&word.to_le_bytes());
    }
    bytes.extend_from_slice(&[0x00, 0x00]);
    bytes.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd]);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_RECORDS_TAG.to_le_bytes());
    bytes.extend_from_slice(&record_body);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_CLOSE_TAG.to_le_bytes());

    let report = inspect_smp_bytes(&bytes);
    let summary = report
        .event_runtime_collection_summary
        .as_ref()
        .expect("event runtime collection summary should parse");

    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .metric
            .as_deref(),
        Some("Cargo Production: Cargo Production Slot 1")
    );
    assert_eq!(
        summary.records[0].standalone_condition_rows[0].recovered_cargo_slot,
        Some(1)
    );
    assert_eq!(
        summary.records[0].decoded_conditions,
        vec![RuntimeCondition::CargoProductionSlotThreshold {
            slot: 1,
            label: "Cargo Production Slot 1".to_string(),
            comparator: RuntimeConditionComparator::Eq,
            value: 125,
        }]
    );
}

#[test]
fn decodes_real_world_scalar_thresholds_from_checked_in_metadata() {
    let condition_rows = vec![
        build_real_condition_row_with_threshold(
            REAL_CARGO_PRODUCTION_TOTAL_CONDITION_ID,
            0,
            200,
            None,
        ),
        build_real_condition_row_with_threshold(
            REAL_FACTORY_PRODUCTION_TOTAL_CONDITION_ID,
            4,
            125,
            None,
        ),
        build_real_condition_row_with_threshold(
            REAL_FARM_MINE_PRODUCTION_TOTAL_CONDITION_ID,
            4,
            75,
            None,
        ),
        build_real_condition_row_with_threshold(
            REAL_OTHER_CARGO_PRODUCTION_TOTAL_CONDITION_ID,
            4,
            30,
            None,
        ),
        build_real_condition_row_with_threshold(
            REAL_LIMITED_TRACK_BUILDING_AMOUNT_CONDITION_ID,
            4,
            18,
            None,
        ),
        build_real_condition_row_with_threshold(
            REAL_TERRITORY_ACCESS_COST_CONDITION_ID,
            4,
            750000,
            None,
        ),
    ];
    let record_body = build_real_event_record(
        [b"World", b"", b"", b"", b"", b""],
        Some(RealCompactControlSpec {
            mode_byte_0x7ef: 7,
            primary_selector_0x7f0: 0,
            grouped_mode_0x7f4: 2,
            one_shot_header_0x7f5: 0,
            modifier_flag_0x7f9: 0,
            modifier_flag_0x7fa: 0,
            grouped_target_scope_ordinals_0x7fb: [0, 0, 0, 0],
            grouped_scope_checkboxes_0x7ff: [0, 0, 0, 0],
            summary_toggle_0x800: 1,
            grouped_territory_selectors_0x80f: [-1, -1, -1, -1],
        }),
        &condition_rows,
        [&[], &[], &[], &[]],
    );

    let mut bytes = Vec::new();
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_METADATA_TAG.to_le_bytes());
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION.to_le_bytes());
    let header_words = [1u32, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for word in header_words {
        bytes.extend_from_slice(&word.to_le_bytes());
    }
    bytes.extend_from_slice(&[0x00, 0x00]);
    bytes.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd]);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_RECORDS_TAG.to_le_bytes());
    bytes.extend_from_slice(&record_body);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_CLOSE_TAG.to_le_bytes());

    let report = inspect_smp_bytes(&bytes);
    let summary = report
        .event_runtime_collection_summary
        .as_ref()
        .expect("event runtime collection summary should parse");

    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .metric
            .as_deref(),
        Some("Cargo Production Total")
    );
    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .semantic_family
            .as_deref(),
        Some("world_scalar_threshold")
    );
    assert_eq!(
        summary.records[0].decoded_conditions,
        vec![
            RuntimeCondition::CargoProductionTotalThreshold {
                comparator: RuntimeConditionComparator::Ge,
                value: 200,
            },
            RuntimeCondition::FactoryProductionTotalThreshold {
                comparator: RuntimeConditionComparator::Eq,
                value: 125,
            },
            RuntimeCondition::FarmMineProductionTotalThreshold {
                comparator: RuntimeConditionComparator::Eq,
                value: 75,
            },
            RuntimeCondition::OtherCargoProductionTotalThreshold {
                comparator: RuntimeConditionComparator::Eq,
                value: 30,
            },
            RuntimeCondition::LimitedTrackBuildingAmountThreshold {
                comparator: RuntimeConditionComparator::Eq,
                value: 18,
            },
            RuntimeCondition::TerritoryAccessCostThreshold {
                comparator: RuntimeConditionComparator::Eq,
                value: 750000,
            },
        ]
    );
}

#[test]
fn decodes_real_world_flag_condition_from_checked_in_world_condition_metadata() {
    let condition_row = build_real_condition_row_with_threshold(2535, 4, 1, None);
    let record_body = build_real_event_record(
        [b"World", b"", b"", b"", b"", b""],
        Some(RealCompactControlSpec {
            mode_byte_0x7ef: 7,
            primary_selector_0x7f0: 0,
            grouped_mode_0x7f4: 2,
            one_shot_header_0x7f5: 0,
            modifier_flag_0x7f9: 0,
            modifier_flag_0x7fa: 0,
            grouped_target_scope_ordinals_0x7fb: [0, 0, 0, 0],
            grouped_scope_checkboxes_0x7ff: [0, 0, 0, 0],
            summary_toggle_0x800: 1,
            grouped_territory_selectors_0x80f: [-1, -1, -1, -1],
        }),
        &[condition_row],
        [&[], &[], &[], &[]],
    );

    let mut bytes = Vec::new();
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_METADATA_TAG.to_le_bytes());
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION.to_le_bytes());
    let header_words = [1u32, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for word in header_words {
        bytes.extend_from_slice(&word.to_le_bytes());
    }
    bytes.extend_from_slice(&[0x00, 0x00]);
    bytes.extend_from_slice(&[0xaa, 0xbb, 0xcc, 0xdd]);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_RECORDS_TAG.to_le_bytes());
    bytes.extend_from_slice(&record_body);
    bytes.extend_from_slice(&EVENT_RUNTIME_COLLECTION_CLOSE_TAG.to_le_bytes());

    let report = inspect_smp_bytes(&bytes);
    let summary = report
        .event_runtime_collection_summary
        .as_ref()
        .expect("event runtime collection summary should parse");

    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .metric
            .as_deref(),
        Some("World Flag: Disable Stock Buying and Selling")
    );
    assert_eq!(
        summary.records[0].standalone_condition_rows[0]
            .semantic_family
            .as_deref(),
        Some("world_flag_equals")
    );
    assert_eq!(
        summary.records[0].decoded_conditions,
        vec![RuntimeCondition::WorldFlagEquals {
            key: "world.disable_stock_buying_and_selling".to_string(),
            value: true,
        }]
    );
}

#[test]
fn looks_up_checked_in_world_scalar_condition_metadata() {
    let named_cargo = real_ordinary_condition_metadata(REAL_CARGO_PRODUCTION_CONDITION_TEMPLATE_ID)
        .expect("named cargo condition metadata should exist");
    assert_eq!(named_cargo.label, "%1 Production");

    let availability =
        real_ordinary_condition_metadata(REAL_NAMED_LOCOMOTIVE_AVAILABILITY_CONDITION_ID)
            .expect("availability condition metadata should exist");
    assert_eq!(availability.label, "Unknown Loco Available");

    let cost = real_ordinary_condition_metadata(REAL_NAMED_LOCOMOTIVE_COST_CONDITION_ID)
        .expect("cost condition metadata should exist");
    assert_eq!(cost.label, "Unknown Loco Cost");

    let cargo = real_ordinary_condition_metadata(REAL_CARGO_PRODUCTION_TOTAL_CONDITION_ID)
        .expect("cargo condition metadata should exist");
    assert_eq!(cargo.label, "All Cargo Production");

    let factory = real_ordinary_condition_metadata(REAL_FACTORY_PRODUCTION_TOTAL_CONDITION_ID)
        .expect("factory production condition metadata should exist");
    assert_eq!(factory.label, "All Factory Production");

    let farm_mine = real_ordinary_condition_metadata(REAL_FARM_MINE_PRODUCTION_TOTAL_CONDITION_ID)
        .expect("farm/mine production condition metadata should exist");
    assert_eq!(farm_mine.label, "All Farm/Mine Production");

    let build_limit =
        real_ordinary_condition_metadata(REAL_LIMITED_TRACK_BUILDING_AMOUNT_CONDITION_ID)
            .expect("build-limit condition metadata should exist");
    assert_eq!(build_limit.label, "Limited Track Building Amount");

    let access_cost = real_ordinary_condition_metadata(REAL_TERRITORY_ACCESS_COST_CONDITION_ID)
        .expect("territory-access-cost condition metadata should exist");
    assert_eq!(access_cost.label, "Access Rights Cost:");
}

#[test]
fn looks_up_checked_in_chairman_and_governance_condition_metadata() {
    let world_variable = real_ordinary_condition_metadata(REAL_WORLD_VARIABLE_1_CONDITION_ID)
        .expect("world-variable condition metadata should exist");
    assert_eq!(world_variable.label, "Game Variable 1");

    let player_variable = real_ordinary_condition_metadata(REAL_PLAYER_VARIABLE_3_CONDITION_ID)
        .expect("player-variable condition metadata should exist");
    assert_eq!(player_variable.label, "Player Variable 3");

    let chairman_cash = real_ordinary_condition_metadata(REAL_CHAIRMAN_CASH_CONDITION_ID)
        .expect("chairman cash condition metadata should exist");
    assert_eq!(chairman_cash.label, "Player Cash");

    let holdings = real_ordinary_condition_metadata(REAL_CHAIRMAN_HOLDINGS_TOTAL_CONDITION_ID)
        .expect("chairman holdings condition metadata should exist");
    assert_eq!(holdings.label, "Player Stock Value");

    let net_worth = real_ordinary_condition_metadata(REAL_CHAIRMAN_NET_WORTH_CONDITION_ID)
        .expect("chairman net worth condition metadata should exist");
    assert_eq!(net_worth.label, "Player Net Worth");

    let purchasing_power =
        real_ordinary_condition_metadata(REAL_CHAIRMAN_PURCHASING_POWER_CONDITION_ID)
            .expect("chairman purchasing-power condition metadata should exist");
    assert_eq!(purchasing_power.label, "Purchasing Power");

    let investor_confidence =
        real_ordinary_condition_metadata(REAL_INVESTOR_CONFIDENCE_CONDITION_ID)
            .expect("investor-confidence condition metadata should exist");
    assert_eq!(investor_confidence.label, "Investor Confidence");

    let credit_rating = real_ordinary_condition_metadata(REAL_CREDIT_RATING_CONDITION_ID)
        .expect("credit-rating condition metadata should exist");
    assert_eq!(credit_rating.label, "Credit Rating");

    let prime_rate = real_ordinary_condition_metadata(REAL_PRIME_RATE_CONDITION_ID)
        .expect("prime-rate condition metadata should exist");
    assert_eq!(prime_rate.label, "Prime Rate");

    let management_attitude =
        real_ordinary_condition_metadata(REAL_MANAGEMENT_ATTITUDE_CONDITION_ID)
            .expect("management-attitude condition metadata should exist");
    assert_eq!(management_attitude.label, "Management Attitude");

    let book_value = real_ordinary_condition_metadata(REAL_BOOK_VALUE_PER_SHARE_CONDITION_ID)
        .expect("book value condition metadata should exist");
    assert_eq!(book_value.label, "Book Value Per Share");
}

#[test]
fn decodes_world_variable_condition() {
    let row = SmpLoadedPackedEventConditionRowSummary {
        row_index: 0,
        raw_condition_id: REAL_WORLD_VARIABLE_1_CONDITION_ID,
        subtype: 4,
        flag_bytes: {
            let mut bytes = vec![0; 25];
            bytes[0..4].copy_from_slice(&111_i32.to_le_bytes());
            bytes
        },
        candidate_name: None,
        comparator: Some("eq".to_string()),
        metric: Some("Game Variable 1".to_string()),
        semantic_family: Some("numeric_threshold".to_string()),
        semantic_preview: Some("Test Game Variable 1 == 111".to_string()),
        recovered_cargo_slot: None,
        recovered_cargo_class: None,
        requires_candidate_name_binding: false,
        notes: vec![],
    };

    assert_eq!(
        decode_real_condition_row(&row, None),
        Some(RuntimeCondition::WorldVariableThreshold {
            index: 1,
            comparator: RuntimeConditionComparator::Eq,
            value: 111,
        })
    );
}

#[test]
fn decodes_player_variable_condition_from_selected_player_scope() {
    let row = SmpLoadedPackedEventConditionRowSummary {
        row_index: 0,
        raw_condition_id: REAL_PLAYER_VARIABLE_3_CONDITION_ID,
        subtype: 4,
        flag_bytes: {
            let mut bytes = vec![0; 25];
            bytes[0..4].copy_from_slice(&333_i32.to_le_bytes());
            bytes
        },
        candidate_name: None,
        comparator: Some("eq".to_string()),
        metric: Some("Player Variable 3".to_string()),
        semantic_family: Some("numeric_threshold".to_string()),
        semantic_preview: Some("Test Player Variable 3 == 333".to_string()),
        recovered_cargo_slot: None,
        recovered_cargo_class: None,
        requires_candidate_name_binding: false,
        notes: vec![],
    };
    let negative_scope = SmpLoadedPackedEventNegativeSentinelScopeSummary {
        company_test_scope: RuntimeCompanyConditionTestScope::Disabled,
        player_test_scope: RuntimePlayerConditionTestScope::SelectedPlayerOnly,
        territory_scope_selector_is_0x63: false,
        source_row_indexes: vec![0],
    };

    assert_eq!(
        decode_real_condition_row(&row, Some(&negative_scope)),
        Some(RuntimeCondition::PlayerVariableThreshold {
            target: RuntimePlayerTarget::SelectedPlayer,
            index: 3,
            comparator: RuntimeConditionComparator::Eq,
            value: 333,
        })
    );
}

#[test]
fn decodes_territory_variable_condition_with_world_territory_scope() {
    let row = SmpLoadedPackedEventConditionRowSummary {
        row_index: 0,
        raw_condition_id: REAL_TERRITORY_VARIABLE_4_CONDITION_ID,
        subtype: 4,
        flag_bytes: {
            let mut bytes = vec![0; 25];
            bytes[0..4].copy_from_slice(&444_i32.to_le_bytes());
            bytes
        },
        candidate_name: None,
        comparator: Some("eq".to_string()),
        metric: Some("Territory Variable 4".to_string()),
        semantic_family: Some("numeric_threshold".to_string()),
        semantic_preview: Some("Test Territory Variable 4 == 444".to_string()),
        recovered_cargo_slot: None,
        recovered_cargo_class: None,
        requires_candidate_name_binding: false,
        notes: vec![],
    };
    let negative_scope = SmpLoadedPackedEventNegativeSentinelScopeSummary {
        company_test_scope: RuntimeCompanyConditionTestScope::Disabled,
        player_test_scope: RuntimePlayerConditionTestScope::Disabled,
        territory_scope_selector_is_0x63: true,
        source_row_indexes: vec![0],
    };

    assert_eq!(
        decode_real_condition_row(&row, Some(&negative_scope)),
        Some(RuntimeCondition::TerritoryVariableThreshold {
            target: RuntimeTerritoryTarget::AllTerritories,
            index: 4,
            comparator: RuntimeConditionComparator::Eq,
            value: 444,
        })
    );
}

#[test]
fn decodes_chairman_cash_condition_from_selected_player_scope() {
    let row = SmpLoadedPackedEventConditionRowSummary {
        row_index: 0,
        raw_condition_id: REAL_CHAIRMAN_CASH_CONDITION_ID,
        subtype: 4,
        flag_bytes: {
            let mut bytes = vec![0; 25];
            bytes[0..4].copy_from_slice(&500_i32.to_le_bytes());
            bytes
        },
        candidate_name: None,
        comparator: Some("eq".to_string()),
        metric: Some("Player Cash".to_string()),
        semantic_family: Some("numeric_threshold".to_string()),
        semantic_preview: Some("Test Player Cash == 500".to_string()),
        recovered_cargo_slot: None,
        recovered_cargo_class: None,
        requires_candidate_name_binding: false,
        notes: vec![],
    };
    let negative_scope = SmpLoadedPackedEventNegativeSentinelScopeSummary {
        company_test_scope: RuntimeCompanyConditionTestScope::Disabled,
        player_test_scope: RuntimePlayerConditionTestScope::SelectedPlayerOnly,
        territory_scope_selector_is_0x63: false,
        source_row_indexes: vec![0],
    };

    assert_eq!(
        decode_real_condition_row(&row, Some(&negative_scope)),
        Some(RuntimeCondition::ChairmanNumericThreshold {
            target: RuntimeChairmanTarget::SelectedChairman,
            metric: RuntimeChairmanMetric::CurrentCash,
            comparator: RuntimeConditionComparator::Eq,
            value: 500,
        })
    );
}

#[test]
fn decodes_book_value_per_share_condition_to_company_metric() {
    let row = SmpLoadedPackedEventConditionRowSummary {
        row_index: 0,
        raw_condition_id: REAL_BOOK_VALUE_PER_SHARE_CONDITION_ID,
        subtype: 4,
        flag_bytes: {
            let mut bytes = vec![0; 25];
            bytes[0..4].copy_from_slice(&2620_i32.to_le_bytes());
            bytes
        },
        candidate_name: None,
        comparator: Some("eq".to_string()),
        metric: Some("Book Value Per Share".to_string()),
        semantic_family: Some("numeric_threshold".to_string()),
        semantic_preview: Some("Test Book Value Per Share == 2620".to_string()),
        recovered_cargo_slot: None,
        recovered_cargo_class: None,
        requires_candidate_name_binding: false,
        notes: vec![],
    };

    assert_eq!(
        decode_real_condition_row(&row, None),
        Some(RuntimeCondition::CompanyNumericThreshold {
            target: RuntimeCompanyTarget::ConditionTrueCompany,
            metric: RuntimeCompanyMetric::BookValuePerShare,
            comparator: RuntimeConditionComparator::Eq,
            value: 2620,
        })
    );
}

#[test]
fn decodes_investor_confidence_condition_to_company_metric() {
    let row = SmpLoadedPackedEventConditionRowSummary {
        row_index: 0,
        raw_condition_id: REAL_INVESTOR_CONFIDENCE_CONDITION_ID,
        subtype: 4,
        flag_bytes: {
            let mut bytes = vec![0; 25];
            bytes[0..4].copy_from_slice(&37_i32.to_le_bytes());
            bytes
        },
        candidate_name: None,
        comparator: Some("eq".to_string()),
        metric: Some("Investor Confidence".to_string()),
        semantic_family: Some("numeric_threshold".to_string()),
        semantic_preview: Some("Test Investor Confidence == 37".to_string()),
        recovered_cargo_slot: None,
        recovered_cargo_class: None,
        requires_candidate_name_binding: false,
        notes: vec![],
    };

    assert_eq!(
        decode_real_condition_row(&row, None),
        Some(RuntimeCondition::CompanyNumericThreshold {
            target: RuntimeCompanyTarget::ConditionTrueCompany,
            metric: RuntimeCompanyMetric::InvestorConfidence,
            comparator: RuntimeConditionComparator::Eq,
            value: 37,
        })
    );
}

#[test]
fn decodes_management_attitude_condition_to_company_metric() {
    let row = SmpLoadedPackedEventConditionRowSummary {
        row_index: 0,
        raw_condition_id: REAL_MANAGEMENT_ATTITUDE_CONDITION_ID,
        subtype: 4,
        flag_bytes: {
            let mut bytes = vec![0; 25];
            bytes[0..4].copy_from_slice(&58_i32.to_le_bytes());
            bytes
        },
        candidate_name: None,
        comparator: Some("eq".to_string()),
        metric: Some("Management Attitude".to_string()),
        semantic_family: Some("numeric_threshold".to_string()),
        semantic_preview: Some("Test Management Attitude == 58".to_string()),
        recovered_cargo_slot: None,
        recovered_cargo_class: None,
        requires_candidate_name_binding: false,
        notes: vec![],
    };

    assert_eq!(
        decode_real_condition_row(&row, None),
        Some(RuntimeCondition::CompanyNumericThreshold {
            target: RuntimeCompanyTarget::ConditionTrueCompany,
            metric: RuntimeCompanyMetric::ManagementAttitude,
            comparator: RuntimeConditionComparator::Eq,
            value: 58,
        })
    );
}
