use super::*;

#[test]
fn reports_grounded_tag_hits_and_offsets() {
    let bytes = [
        0x34, 0x12, 0x00, 0x00, 0xe0, 0x2e, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x80, 0x02,
        0x00, 0x00, 0x00, 0x01, 0x00, 0x71, 0x07, 0x00, 0x00, 0x71, 0x07, 0x00, 0x00, 0x71, 0x07,
        0x00, 0x00, 0xaa, 0xbb, 0x00, 0x00, 0xcc, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, b'H', b'e', b'l', b'l', b'o', b' ', b'R', b'R',
        b'T', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x22,
        0x33, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x00, 0x00, 0x00, 0x00,
        0xee, 0x2c, 0x11, 0x51, 0x2d, 0x22, 0x71, 0x94, 0x33, 0x72, 0x94,
    ];
    let report = inspect_smp_bytes(&bytes);

    assert!(report.contains_grounded_runtime_tags);
    assert_eq!(report.known_tag_hits.len(), 4);
    assert_eq!(report.preamble.word_count, 16);
    assert_eq!(report.preamble.words[0].value_le, 0x00001234);
    let shared_header = report
        .shared_header
        .as_ref()
        .expect("shared header should parse");
    assert!(shared_header.matches_grounded_common_signature);
    let header_variant = report
        .header_variant_probe
        .as_ref()
        .expect("header variant probe should exist");
    assert_eq!(header_variant.variant_family, "unknown");
    assert!(!header_variant.is_known_family);
    assert_eq!(shared_header.primary_family_tag, 0x00002ee0);
    assert_eq!(
        shared_header.payload_window_words_8_to_9,
        vec![0x0000bbaa, 0x0000ddcc]
    );
    assert!(shared_header.reserved_words_10_to_14_all_zero);
    assert_eq!(shared_header.final_flag_word, 0);
    let ascii_run = report
        .first_ascii_run
        .as_ref()
        .expect("ascii run should exist");
    assert_eq!(ascii_run.offset, 67);
    assert_eq!(ascii_run.byte_len, 9);
    assert_eq!(ascii_run.preview, "Hello RRT");
    let early_probe = report
        .early_content_probe
        .as_ref()
        .expect("early content probe should exist");
    assert_eq!(early_probe.first_post_text_nonzero_offset, 88);
    assert_eq!(early_probe.zero_pad_after_text_len, 12);
    assert_eq!(early_probe.first_post_text_block_len, 4);
    assert_eq!(early_probe.first_post_text_block_hex, "11223344");
    assert_eq!(early_probe.trailing_zero_pad_after_first_block_len, 16);
    assert_eq!(early_probe.secondary_nonzero_offset, Some(108));
    assert_eq!(early_probe.secondary_aligned_word_window_offset, Some(108));
    assert_eq!(
        &early_probe.secondary_aligned_word_window_words[..2],
        &[0x78563412, 0xf0debc9a]
    );
    assert!(
        early_probe
            .secondary_preview_hex
            .starts_with("123456789abcdef0")
    );
    let secondary_variant = report
        .secondary_variant_probe
        .as_ref()
        .expect("secondary variant probe should exist");
    assert_eq!(secondary_variant.variant_family, "unknown");
    let container_profile = report
        .container_profile
        .as_ref()
        .expect("container profile should exist");
    assert_eq!(container_profile.profile_family, "unknown");
    assert!(!container_profile.is_known_profile);
    assert!(report.save_bootstrap_block.is_none());
    assert!(report.save_anchor_run_block.is_none());
    assert!(report.runtime_anchor_cycle_block.is_none());
    assert!(report.runtime_trailer_block.is_none());
    assert!(report.runtime_post_span_probe.is_none());
    assert!(report.classic_rehydrate_profile_probe.is_none());
    assert_eq!(report.known_tag_hits[0].tag_id, 0x2cee);
    assert_eq!(report.known_tag_hits[0].hit_count, 1);
    assert_eq!(report.known_tag_hits[0].sample_offsets, vec![120]);
    assert_eq!(report.known_tag_hits[1].tag_id, 0x2d51);
    assert_eq!(report.known_tag_hits[1].sample_offsets, vec![123]);
    assert_eq!(report.known_tag_hits[2].tag_id, 0x9471);
    assert_eq!(report.known_tag_hits[2].sample_offsets, vec![126]);
    assert_eq!(report.known_tag_hits[3].tag_id, 0x9472);
    assert_eq!(report.known_tag_hits[3].sample_offsets, vec![129]);
}

#[test]
fn warns_when_no_grounded_tags_are_present() {
    let report = inspect_smp_bytes(&[0xaa, 0xbb, 0xcc]);

    assert!(!report.contains_grounded_runtime_tags);
    assert!(report.known_tag_hits.is_empty());
    assert_eq!(report.preamble.word_count, 0);
    assert!(report.shared_header.is_none());
    assert!(report.header_variant_probe.is_none());
    assert!(report.first_ascii_run.is_none());
    assert!(report.early_content_probe.is_none());
    assert!(report.secondary_variant_probe.is_none());
    assert!(report.container_profile.is_none());
    assert!(report.save_bootstrap_block.is_none());
    assert!(report.save_anchor_run_block.is_none());
    assert!(report.runtime_anchor_cycle_block.is_none());
    assert!(report.runtime_trailer_block.is_none());
    assert!(report.runtime_post_span_probe.is_none());
    assert!(report.classic_rehydrate_profile_probe.is_none());
    assert!(
        report
            .warnings
            .iter()
            .any(|warning| warning.contains("No grounded runtime bundle tags were found"))
    );
}

#[test]
fn parses_save_anchor_cycle_and_trailer() {
    let cycle_words: [u32; 9] = [
        0x00000000, 0x0186a000, 0x00000000, 0x86a00000, 0x00000001, 0xa0000000, 0x00000186,
        0x00000000, 0x000186a0,
    ];
    let trailer_words: [u32; 3] = [0x00020000, 0x00030000, 0x2ee10000];
    let mut bytes = vec![0u8; 0x1c + (cycle_words.len() * 2 + 2 + trailer_words.len()) * 4];

    let mut cursor = 0x1c;
    for _ in 0..2 {
        for word in cycle_words {
            bytes[cursor..cursor + 4].copy_from_slice(&word.to_le_bytes());
            cursor += 4;
        }
    }
    for word in &cycle_words[..2] {
        bytes[cursor..cursor + 4].copy_from_slice(&(*word).to_le_bytes());
        cursor += 4;
    }
    for word in trailer_words {
        bytes[cursor..cursor + 4].copy_from_slice(&word.to_le_bytes());
        cursor += 4;
    }

    let container_profile = SmpContainerProfile {
        profile_family: "rt3-classic-save-container-v1".to_string(),
        profile_evidence: vec!["test".to_string()],
        is_known_profile: true,
    };
    let bootstrap = SmpSaveBootstrapBlock {
        profile_family: "rt3-classic-save-container-v1".to_string(),
        aligned_window_offset: 0,
        leading_word: 0,
        leading_word_hex: "0x00000000".to_string(),
        anchor_word: 0,
        anchor_word_hex: "0x00000000".to_string(),
        descriptor_word_2: 0,
        descriptor_word_2_hex: "0x00000000".to_string(),
        descriptor_word_3: 0,
        descriptor_word_3_hex: "0x00000000".to_string(),
        descriptor_word_4: 0,
        descriptor_word_4_hex: "0x00000000".to_string(),
        descriptor_word_5: 0,
        descriptor_word_5_hex: "0x00000000".to_string(),
        descriptor_word_6: 0,
        descriptor_word_6_hex: "0x00000000".to_string(),
        descriptor_word_7: 0,
        descriptor_word_7_hex: "0x00000000".to_string(),
    };

    let parsed = parse_save_anchor_run_block(&bytes, Some(&container_profile), Some(&bootstrap))
        .expect("cycle block should parse");

    assert_eq!(parsed.cycle_start_offset, 0x1c);
    assert_eq!(parsed.cycle_words, cycle_words);
    assert_eq!(parsed.full_cycle_count, 2);
    assert_eq!(parsed.partial_cycle_word_count, 2);
    assert_eq!(
        parsed.trailer_offset,
        0x1c + (cycle_words.len() * 2 + 2) * 4
    );
    assert_eq!(parsed.trailer_words, trailer_words);
}

#[test]
fn classifies_runtime_trailer_family() {
    let runtime_anchor_cycle_block = SmpRuntimeAnchorCycleBlock {
        profile_family: "rt3-classic-sandbox-container-v1".to_string(),
        cycle_start_offset: 0x33c,
        cycle_words: vec![0; 9],
        cycle_hex_words: vec!["0x00000000".to_string(); 9],
        full_cycle_count: 3,
        partial_cycle_word_count: 2,
        trailer_offset: 0x3b0,
        trailer_words: vec![
            0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000, 0x2ee10000,
            0x32c80000, 0x0dcd0000, 0x01010107, 0x26010000, 0x01010107, 0x00010000, 0x0334c68c,
            0x03000000, 0x01000000,
        ],
        trailer_hex_words: Vec::new(),
    };
    let container_profile = SmpContainerProfile {
        profile_family: "rt3-classic-sandbox-container-v1".to_string(),
        profile_evidence: vec!["test".to_string()],
        is_known_profile: true,
    };

    let trailer =
        parse_runtime_trailer_block(Some(&container_profile), Some(&runtime_anchor_cycle_block))
            .expect("runtime trailer should parse");

    assert_eq!(trailer.trailer_family, "rt3-classic-sandbox-trailer-v1");
    assert_eq!(trailer.prefix_words_0_to_5[0], 0x00010000);
    assert_eq!(trailer.tag_word_6, 0x2ee10000);
    assert_eq!(trailer.tag_chunk_id_u16, 0x2ee1);
    assert_eq!(trailer.selector_word_8, 0x0dcd0000);
    assert_eq!(trailer.selector_high_u16, 0x0dcd);
    assert_eq!(trailer.mode_word_15, 0x01000000);
}

#[test]
fn probes_runtime_post_span_region() {
    let mut bytes = vec![0u8; 0x200];
    bytes[0x90..0x94].copy_from_slice(&0x32dc0000u32.to_le_bytes());
    bytes[0x94..0x98].copy_from_slice(&0x37140000u32.to_le_bytes());
    bytes[0x98..0x9c].copy_from_slice(&0x03000000u32.to_le_bytes());
    bytes[0xa0..0xa4].copy_from_slice(&0x37150000u32.to_le_bytes());
    bytes[0xa4..0xa8].copy_from_slice(&0x00010000u32.to_le_bytes());
    bytes[0xa8..0xac].copy_from_slice(&0x00410000u32.to_le_bytes());

    let trailer = SmpRuntimeTrailerBlock {
        profile_family: "rt3-classic-save-container-v1".to_string(),
        trailer_family: "test".to_string(),
        trailer_evidence: Vec::new(),
        trailer_offset: 0x40,
        prefix_words_0_to_5: Vec::new(),
        prefix_hex_words_0_to_5: Vec::new(),
        tag_word_6: 0x2ee10000,
        tag_word_6_hex: "0x2ee10000".to_string(),
        tag_chunk_id_u16: 0x2ee1,
        tag_chunk_id_hex: "0x2ee1".to_string(),
        tag_chunk_id_grounded_alignment: None,
        length_word_7: 0x00200000,
        length_word_7_hex: "0x00200000".to_string(),
        length_high_u16: 0x0020,
        length_high_hex: "0x0020".to_string(),
        selector_word_8: 0,
        selector_word_8_hex: "0x00000000".to_string(),
        selector_high_u16: 0,
        selector_high_hex: "0x0000".to_string(),
        layout_word_9: 0,
        layout_word_9_hex: "0x00000000".to_string(),
        descriptor_word_10: 0,
        descriptor_word_10_hex: "0x00000000".to_string(),
        descriptor_high_u16: 0,
        descriptor_high_hex: "0x0000".to_string(),
        descriptor_word_11: 0,
        descriptor_word_11_hex: "0x00000000".to_string(),
        counter_word_12: 0,
        counter_word_12_hex: "0x00000000".to_string(),
        offset_word_13: 0,
        offset_word_13_hex: "0x00000000".to_string(),
        span_word_14: 0,
        span_word_14_hex: "0x00000000".to_string(),
        mode_word_15: 0,
        mode_word_15_hex: "0x00000000".to_string(),
        words: Vec::new(),
        hex_words: Vec::new(),
    };

    let probe = parse_runtime_post_span_probe(&bytes, Some(&trailer))
        .expect("post-span probe should parse");

    assert_eq!(probe.span_target_offset, 0x60);
    assert_eq!(probe.next_nonzero_offset, Some(0x92));
    assert_eq!(probe.next_aligned_candidate_offset, Some(0x8c));
    assert_eq!(probe.header_candidates.len(), 1);
    assert_eq!(probe.header_candidates[0].dense_word_count, 3);
    assert_eq!(probe.header_candidates[0].grounded_alignments.len(), 2);
    assert_eq!(probe.grounded_progress_hits[0], "0x32dc@0x00000090");
}

#[test]
fn parses_classic_rehydrate_profile_probe() {
    let mut bytes = vec![0u8; 0x220];
    bytes[0x90..0x94].copy_from_slice(&0x32dc0000u32.to_le_bytes());
    bytes[0x94..0x98].copy_from_slice(&0x37140000u32.to_le_bytes());
    bytes[0x1a0..0x1a4].copy_from_slice(&0x37150000u32.to_le_bytes());
    bytes[0xab..0xb7].copy_from_slice(b"test-map.gmp");
    bytes[0xde..0xe6].copy_from_slice(b"Test Map");

    let post_span = SmpRuntimePostSpanProbe {
        profile_family: "rt3-classic-save-container-v1".to_string(),
        span_target_offset: 0,
        next_nonzero_offset: Some(0x92),
        next_aligned_candidate_offset: Some(0x8c),
        next_aligned_candidate_words: vec![0, 0x32dc0000, 0x37140000, 0x03000000],
        next_aligned_candidate_hex_words: vec![],
        header_candidates: vec![],
        grounded_progress_hits: vec![
            "0x32dc@0x00000090".to_string(),
            "0x3714@0x00000094".to_string(),
            "0x3715@0x000001a0".to_string(),
        ],
    };

    let probe = parse_classic_rehydrate_profile_probe(&bytes, Some(&post_span))
        .expect("classic rehydrate probe should parse");

    assert_eq!(probe.packed_profile_offset, 0x98);
    assert_eq!(probe.packed_profile_len, 0x108);
    assert_eq!(probe.ascii_runs[0].preview, "test-map.gmp");
    assert_eq!(probe.packed_profile_block.leading_word_0, 0x00000000);
    assert_eq!(
        probe.packed_profile_block.map_path.as_deref(),
        Some("test-map.gmp")
    );
    assert_eq!(
        probe.packed_profile_block.display_name.as_deref(),
        Some("Test Map")
    );
    assert_eq!(probe.packed_profile_block.profile_byte_0x77, 0x00);
    assert_eq!(probe.packed_profile_block.profile_byte_0x82, 0x00);
    assert_eq!(probe.packed_profile_block.profile_byte_0x97, 0x00);
    assert_eq!(probe.packed_profile_block.profile_byte_0xc5, 0x00);
}

#[test]
fn parses_rt3_105_packed_profile_probe() {
    let mut bytes = vec![0u8; 0x9000];
    let block = 0x73c0usize;
    bytes[block..block + 4].copy_from_slice(&0x00000003u32.to_le_bytes());
    bytes[block + 0x0c..block + 0x10].copy_from_slice(&0x01000000u32.to_le_bytes());
    bytes[block + 0x10..block + 0x1d].copy_from_slice(b"test-105.gmp\0");
    bytes[block + 0x43..block + 0x4c].copy_from_slice(b"Test 105\0");
    bytes[block + 0x77] = 0x07;
    bytes[block + 0x82] = 0x4d;
    bytes[block + 0x84..block + 0x88].copy_from_slice(&0x65010000u32.to_le_bytes());

    let header_variant_probe = SmpHeaderVariantProbe {
        variant_family: "rt3-105-common-header-v1".to_string(),
        variant_evidence: vec![],
        is_known_family: true,
    };
    let probe =
        parse_rt3_105_packed_profile_probe(&bytes, Some("gms"), Some(&header_variant_probe), None)
            .expect("1.05 packed profile probe should parse");

    assert_eq!(probe.profile_family, "rt3-105-save-analog-block-inferred");
    assert_eq!(probe.packed_profile_offset, 0x73c0);
    assert_eq!(probe.packed_profile_len, 0x108);
    assert_eq!(
        probe.packed_profile_block.map_path.as_deref(),
        Some("test-105.gmp")
    );
    assert_eq!(
        probe.packed_profile_block.display_name.as_deref(),
        Some("Test 105")
    );
    assert_eq!(probe.packed_profile_block.profile_byte_0x77, 0x07);
    assert_eq!(probe.packed_profile_block.profile_byte_0x82, 0x4d);
    assert_eq!(probe.packed_profile_block.profile_byte_0x97, 0x00);
    assert_eq!(probe.packed_profile_block.profile_byte_0xc5, 0x00);
}

#[test]
fn builds_classic_save_load_summary() {
    let summary = build_save_load_summary(
        Some("gms"),
        Some(&SmpContainerProfile {
            profile_family: "rt3-classic-save-container-v1".to_string(),
            profile_evidence: vec![],
            is_known_profile: true,
        }),
        None,
        None,
        Some(&SmpClassicRehydrateProfileProbe {
            profile_family: "rt3-classic-save-container-v1".to_string(),
            progress_32dc_offset: 0x76e8,
            progress_3714_offset: 0x76ec,
            progress_3715_offset: 0x77f8,
            packed_profile_offset: 0x76f0,
            packed_profile_len: 0x108,
            packed_profile_len_hex: "0x108".to_string(),
            packed_profile_block: SmpClassicPackedProfileBlock {
                relative_len: 0x108,
                relative_len_hex: "0x108".to_string(),
                leading_word_0: 3,
                leading_word_0_hex: "0x00000003".to_string(),
                trailing_zero_word_count_after_leading_word: 3,
                map_path_offset: 0x13,
                map_path: Some("British Isles.gmp".to_string()),
                display_name_offset: 0x46,
                display_name: Some("British Isles".to_string()),
                profile_byte_0x77: 0,
                profile_byte_0x77_hex: "0x00".to_string(),
                profile_byte_0x82: 0,
                profile_byte_0x82_hex: "0x00".to_string(),
                profile_byte_0x97: 0,
                profile_byte_0x97_hex: "0x00".to_string(),
                profile_byte_0xc5: 0,
                profile_byte_0xc5_hex: "0x00".to_string(),
                stable_nonzero_words: vec![],
            },
            ascii_runs: vec![],
        }),
        None,
        None,
    )
    .expect("classic summary");

    assert_eq!(summary.mechanism_family, "classic-save-rehydrate-v1");
    assert_eq!(summary.mechanism_confidence, "grounded");
    assert_eq!(summary.map_path.as_deref(), Some("British Isles.gmp"));
    assert_eq!(summary.packed_profile_len, Some(0x108));
}

#[test]
fn builds_rt3_105_save_load_summary_with_candidate_table() {
    let summary = build_save_load_summary(
        Some("gms"),
        Some(&SmpContainerProfile {
            profile_family: "rt3-105-save-container-v1".to_string(),
            profile_evidence: vec![],
            is_known_profile: true,
        }),
        None,
        Some(&SmpRt3105PostSpanBridgeProbe {
            profile_family: "rt3-105-save-container-v1".to_string(),
            bridge_family: "rt3-105-save-post-span-bridge-v1".to_string(),
            bridge_evidence: vec![],
            span_target_offset: 0x3678,
            next_candidate_offset: Some(0x4f14),
            next_candidate_delta_from_span_target: Some(0x189c),
            packed_profile_offset: 0x73c0,
            packed_profile_delta_from_span_target: 0x3d48,
            next_candidate_delta_from_packed_profile: Some(-0x24ac),
            selector_high_u16: 0x7110,
            selector_high_hex: "0x7110".to_string(),
            descriptor_high_u16: 0x7801,
            descriptor_high_hex: "0x7801".to_string(),
            next_candidate_high_u16_words: vec![0x6200, 0x0000, 0xfff7, 0x5515],
            next_candidate_high_hex_words: vec![],
        }),
        None,
        Some(&SmpRt3105PackedProfileProbe {
            profile_family: "rt3-105-save-container-v1".to_string(),
            packed_profile_offset: 0x73c0,
            packed_profile_len: 0x108,
            packed_profile_len_hex: "0x108".to_string(),
            packed_profile_block: SmpRt3105PackedProfileBlock {
                relative_len: 0x108,
                relative_len_hex: "0x108".to_string(),
                leading_word_0: 3,
                leading_word_0_hex: "0x00000003".to_string(),
                trailing_zero_word_count_after_leading_word: 2,
                header_flag_word_3: 1,
                header_flag_word_3_hex: "0x00000001".to_string(),
                map_path_offset: 0x10,
                map_path: Some("Alternate USA.gmp".to_string()),
                display_name_offset: 0x43,
                display_name: Some("Alternate USA".to_string()),
                profile_byte_0x77: 0x07,
                profile_byte_0x77_hex: "0x07".to_string(),
                profile_byte_0x82: 0x4d,
                profile_byte_0x82_hex: "0x4d".to_string(),
                profile_byte_0x97: 0,
                profile_byte_0x97_hex: "0x00".to_string(),
                profile_byte_0xc5: 0,
                profile_byte_0xc5_hex: "0x00".to_string(),
                stable_nonzero_words: vec![],
            },
            ascii_runs: vec![],
        }),
        Some(&SmpRt3105SaveNameTableProbe {
            profile_family: "rt3-105-save-container-v1".to_string(),
            source_kind: "save-bridge-secondary-block".to_string(),
            semantic_family: "scenario-named-candidate-availability-table".to_string(),
            semantic_alignment: vec![],
            header_offset: 0x6a70,
            header_word_0: 0,
            header_word_0_hex: "0x00000000".to_string(),
            header_word_1: 0,
            header_word_1_hex: "0x00000000".to_string(),
            header_word_2: 0x332e,
            header_word_2_hex: "0x0000332e".to_string(),
            entry_stride: 0x22,
            entry_stride_hex: "0x22".to_string(),
            header_prefix_word_count: 11,
            observed_entry_capacity: 0x44,
            observed_entry_count: 67,
            zero_trailer_entry_count: 3,
            nonzero_trailer_entry_count: 64,
            distinct_trailer_words: vec![0, 1],
            distinct_trailer_hex_words: vec!["0x00000000".to_string(), "0x00000001".to_string()],
            zero_trailer_entry_names: vec![
                "Nuclear Power Plant".to_string(),
                "Recycling Plant".to_string(),
                "Uranium Mine".to_string(),
            ],
            entries_offset: 0x6ad1,
            entries_end_offset: 0x73b7,
            trailing_footer_hex: "dc3200001437000000".to_string(),
            footer_progress_word_0: 0x32dc,
            footer_progress_word_0_hex: "0x000032dc".to_string(),
            footer_progress_word_1: 0x3714,
            footer_progress_word_1_hex: "0x00003714".to_string(),
            footer_trailing_byte: 0,
            footer_trailing_byte_hex: "0x00".to_string(),
            footer_grounded_alignments: vec![],
            entries: vec![],
            evidence: vec![],
        }),
    )
    .expect("1.05 summary");

    assert_eq!(summary.mechanism_family, "rt3-105-save-post-span-bridge-v1");
    assert_eq!(summary.mechanism_confidence, "mixed");
    assert_eq!(summary.map_path.as_deref(), Some("Alternate USA.gmp"));
    assert_eq!(
        summary
            .candidate_table
            .as_ref()
            .expect("candidate table")
            .zero_availability_count,
        3
    );
}

#[test]
fn loads_classic_save_slice_from_report() {
    let mut report = inspect_smp_bytes(&[]);
    let classic_probe = SmpClassicRehydrateProfileProbe {
        profile_family: "rt3-classic-save-container-v1".to_string(),
        progress_32dc_offset: 0x76e8,
        progress_3714_offset: 0x76ec,
        progress_3715_offset: 0x77f8,
        packed_profile_offset: 0x76f0,
        packed_profile_len: 0x108,
        packed_profile_len_hex: "0x108".to_string(),
        packed_profile_block: SmpClassicPackedProfileBlock {
            relative_len: 0x108,
            relative_len_hex: "0x108".to_string(),
            leading_word_0: 3,
            leading_word_0_hex: "0x00000003".to_string(),
            trailing_zero_word_count_after_leading_word: 3,
            map_path_offset: 0x13,
            map_path: Some("British Isles.gmp".to_string()),
            display_name_offset: 0x46,
            display_name: Some("British Isles".to_string()),
            profile_byte_0x77: 0,
            profile_byte_0x77_hex: "0x00".to_string(),
            profile_byte_0x82: 0,
            profile_byte_0x82_hex: "0x00".to_string(),
            profile_byte_0x97: 0,
            profile_byte_0x97_hex: "0x00".to_string(),
            profile_byte_0xc5: 0,
            profile_byte_0xc5_hex: "0x00".to_string(),
            stable_nonzero_words: vec![],
        },
        ascii_runs: vec![],
    };
    report.classic_rehydrate_profile_probe = Some(classic_probe.clone());
    report.save_load_summary = build_save_load_summary(
        Some("gms"),
        Some(&SmpContainerProfile {
            profile_family: "rt3-classic-save-container-v1".to_string(),
            profile_evidence: vec![],
            is_known_profile: true,
        }),
        None,
        None,
        Some(&classic_probe),
        None,
        None,
    );

    let slice = load_save_slice_from_report(&report).expect("classic save slice");
    assert_eq!(slice.mechanism_family, "classic-save-rehydrate-v1");
    assert_eq!(
        slice
            .profile
            .as_ref()
            .and_then(|profile| profile.map_path.as_deref()),
        Some("British Isles.gmp")
    );
    assert!(slice.candidate_availability_table.is_none());
}

#[test]
fn loads_event_runtime_collection_summary_from_report() {
    let mut report = inspect_smp_bytes(&[]);
    let classic_probe = SmpClassicRehydrateProfileProbe {
        profile_family: "rt3-classic-save-container-v1".to_string(),
        progress_32dc_offset: 0x76e8,
        progress_3714_offset: 0x76ec,
        progress_3715_offset: 0x77f8,
        packed_profile_offset: 0x76f0,
        packed_profile_len: 0x108,
        packed_profile_len_hex: "0x108".to_string(),
        packed_profile_block: SmpClassicPackedProfileBlock {
            relative_len: 0x108,
            relative_len_hex: "0x108".to_string(),
            leading_word_0: 3,
            leading_word_0_hex: "0x00000003".to_string(),
            trailing_zero_word_count_after_leading_word: 3,
            map_path_offset: 0x13,
            map_path: Some("British Isles.gmp".to_string()),
            display_name_offset: 0x46,
            display_name: Some("British Isles".to_string()),
            profile_byte_0x77: 0,
            profile_byte_0x77_hex: "0x00".to_string(),
            profile_byte_0x82: 0,
            profile_byte_0x82_hex: "0x00".to_string(),
            profile_byte_0x97: 0,
            profile_byte_0x97_hex: "0x00".to_string(),
            profile_byte_0xc5: 0,
            profile_byte_0xc5_hex: "0x00".to_string(),
            stable_nonzero_words: vec![],
        },
        ascii_runs: vec![],
    };
    report.classic_rehydrate_profile_probe = Some(classic_probe.clone());
    report.save_load_summary = build_save_load_summary(
        Some("gms"),
        Some(&SmpContainerProfile {
            profile_family: "rt3-classic-save-container-v1".to_string(),
            profile_evidence: vec![],
            is_known_profile: true,
        }),
        None,
        None,
        Some(&classic_probe),
        None,
        None,
    );
    report.event_runtime_collection_summary = Some(SmpLoadedEventRuntimeCollectionSummary {
        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()),
        metadata_tag_offset: 0x7100,
        records_tag_offset: 0x7200,
        close_tag_offset: 0x7600,
        packed_state_version: 0x3e9,
        packed_state_version_hex: "0x000003e9".to_string(),
        live_id_bound: 5,
        live_record_count: 3,
        live_entry_ids: vec![1, 3, 5],
        decoded_record_count: 0,
        imported_runtime_record_count: 0,
        records_with_trigger_kind: 0,
        records_missing_trigger_kind: 3,
        nondirect_compact_record_count: 0,
        nondirect_compact_records_missing_trigger_kind: 0,
        trigger_kinds_present: vec![],
        add_building_dispatch_strip_record_indexes: vec![],
        add_building_dispatch_strip_descriptor_labels: vec![],
        add_building_dispatch_strip_records_with_trigger_kind: 0,
        add_building_dispatch_strip_records_missing_trigger_kind: 0,
        add_building_dispatch_strip_row_shape_families: vec![],
        add_building_dispatch_strip_signature_families: vec![],
        add_building_dispatch_strip_condition_tuple_families: vec![],
        add_building_dispatch_strip_signature_condition_clusters: vec![],
        control_lane_notes: vec![],
        records: build_unsupported_event_runtime_record_summaries(&[1, 3, 5], "test summary"),
    });

    let slice = load_save_slice_from_report(&report).expect("classic save slice");
    assert_eq!(
        slice
            .event_runtime_collection
            .as_ref()
            .map(|summary| summary.live_entry_ids.clone()),
        Some(vec![1, 3, 5])
    );
}

#[test]
fn loads_placed_structure_collection_from_report() {
    let mut report = inspect_smp_bytes(&[]);
    let classic_probe = SmpClassicRehydrateProfileProbe {
        profile_family: "rt3-classic-save-container-v1".to_string(),
        progress_32dc_offset: 0x76e8,
        progress_3714_offset: 0x76ec,
        progress_3715_offset: 0x77f8,
        packed_profile_offset: 0x76f0,
        packed_profile_len: 0x108,
        packed_profile_len_hex: "0x108".to_string(),
        packed_profile_block: SmpClassicPackedProfileBlock {
            relative_len: 0x108,
            relative_len_hex: "0x108".to_string(),
            leading_word_0: 3,
            leading_word_0_hex: "0x00000003".to_string(),
            trailing_zero_word_count_after_leading_word: 3,
            map_path_offset: 0x13,
            map_path: Some("British Isles.gmp".to_string()),
            display_name_offset: 0x46,
            display_name: Some("British Isles".to_string()),
            profile_byte_0x77: 0,
            profile_byte_0x77_hex: "0x00".to_string(),
            profile_byte_0x82: 0,
            profile_byte_0x82_hex: "0x00".to_string(),
            profile_byte_0x97: 0,
            profile_byte_0x97_hex: "0x00".to_string(),
            profile_byte_0xc5: 0,
            profile_byte_0xc5_hex: "0x00".to_string(),
            stable_nonzero_words: vec![],
        },
        ascii_runs: vec![],
    };
    report.classic_rehydrate_profile_probe = Some(classic_probe.clone());
    report.save_load_summary = build_save_load_summary(
        Some("gms"),
        Some(&SmpContainerProfile {
            profile_family: "rt3-classic-save-container-v1".to_string(),
            profile_evidence: vec![],
            is_known_profile: true,
        }),
        None,
        None,
        Some(&classic_probe),
        None,
        None,
    );
    report.save_region_record_triplet_probe = Some(SmpSaveRegionRecordTripletProbe {
        profile_family: "rt3-classic-save-container-v1".to_string(),
        source_kind: "save-region-record-triplets".to_string(),
        semantic_family: "scenario-save-region-record-triplets".to_string(),
        records_tag_offset: 0x3400,
        close_tag_offset: 0x3500,
        record_count: 2,
        entries: vec![
            SmpSaveRegionRecordTripletEntryProbe {
                record_index: 0,
                name: "Marker09".to_string(),
                record_payload_relative_offset: 0,
                record_payload_relative_offset_hex: "0x0".to_string(),
                name_tag_relative_offset: 0,
                policy_tag_relative_offset: 0x10,
                profile_tag_relative_offset: 0x2e,
                pre_name_prefix_len: 0,
                pre_name_prefix_hex_bytes: Vec::new(),
                pre_name_prefix_dword_candidates: Vec::new(),
                policy_chunk_len: 0x1a,
                profile_chunk_len: 0x40,
                policy_leading_f32_0: 368.0,
                policy_leading_f32_1: 0.0,
                policy_leading_f32_2: 92.0,
                policy_reserved_dwords: vec![0, 0, 0],
                policy_reserved_dword_candidates: Vec::new(),
                policy_trailing_word: 1,
                policy_trailing_word_hex: "0x0001".to_string(),
                profile_collection: Some(SmpSaveRegionProfileCollectionProbe {
                    direct_collection_flag: 1,
                    entry_stride: 0x22,
                    live_id_bound: 18,
                    live_record_count: 17,
                    entry_start_relative_offset: 0x4d,
                    trailing_padding_len: 2,
                    entries: vec![
                        SmpSaveRegionProfileEntryProbe {
                            entry_index: 0,
                            row_relative_offset: 0x4d,
                            name: "House".to_string(),
                            trailing_weight_f32: 0.2,
                        },
                        SmpSaveRegionProfileEntryProbe {
                            entry_index: 1,
                            row_relative_offset: 0x6f,
                            name: "Farm Corn".to_string(),
                            trailing_weight_f32: 0.2,
                        },
                    ],
                }),
            },
            SmpSaveRegionRecordTripletEntryProbe {
                record_index: 1,
                name: "Marker10".to_string(),
                record_payload_relative_offset: 0x6e,
                record_payload_relative_offset_hex: "0x6e".to_string(),
                name_tag_relative_offset: 0x76,
                policy_tag_relative_offset: 0x86,
                profile_tag_relative_offset: 0xa4,
                pre_name_prefix_len: 8,
                pre_name_prefix_hex_bytes: vec![
                    "0xaa".to_string(),
                    "0xbb".to_string(),
                    "0xcc".to_string(),
                    "0xdd".to_string(),
                ],
                pre_name_prefix_dword_candidates: Vec::new(),
                policy_chunk_len: 0x1a,
                profile_chunk_len: 0x20,
                policy_leading_f32_0: 552.0,
                policy_leading_f32_1: 0.0,
                policy_leading_f32_2: 276.0,
                policy_reserved_dwords: vec![0, 4, 0],
                policy_reserved_dword_candidates: Vec::new(),
                policy_trailing_word: 1,
                policy_trailing_word_hex: "0x0001".to_string(),
                profile_collection: Some(SmpSaveRegionProfileCollectionProbe {
                    direct_collection_flag: 1,
                    entry_stride: 0x22,
                    live_id_bound: 26,
                    live_record_count: 24,
                    entry_start_relative_offset: 0x50,
                    trailing_padding_len: 0,
                    entries: vec![SmpSaveRegionProfileEntryProbe {
                        entry_index: 0,
                        row_relative_offset: 0x50,
                        name: "Farm Corn".to_string(),
                        trailing_weight_f32: 0.2,
                    }],
                }),
            },
        ],
        evidence: vec![],
    });
    report.save_region_fixed_row_run_candidate_probe =
        Some(SmpSaveRegionFixedRowRunCandidateProbe {
            profile_family: "rt3-classic-save-container-v1".to_string(),
            source_kind: "save-region-fixed-row-run-candidates".to_string(),
            semantic_family: "scenario-save-region-fixed-row-run-candidates".to_string(),
            target_row_count: 2,
            target_row_stride: 0xbc,
            target_row_stride_hex: "0xbc".to_string(),
            scan_start_offset: 0x5200,
            scan_start_offset_hex: "0x5200".to_string(),
            scan_end_offset: 0x5600,
            scan_end_offset_hex: "0x5600".to_string(),
            candidates: vec![SmpSaveRegionFixedRowRunCandidate {
                count_offset: 0x5300,
                count_offset_hex: "0x5300".to_string(),
                row_count: 2,
                row_stride: 0xbc,
                row_stride_hex: "0xbc".to_string(),
                rows_offset: 0x5310,
                rows_offset_hex: "0x5310".to_string(),
                rows_end_offset: 0x5488,
                rows_end_offset_hex: "0x5488".to_string(),
                distance_to_region_metadata_tag: 0x110,
                distance_to_region_metadata_tag_hex: "0x110".to_string(),
                dword_lane_summaries: vec![],
                shape_signature: "dword0:f32,dword1:zero".to_string(),
                shape_family_signature: "family-a".to_string(),
                trailing_byte_zero_count: 2,
                trailing_byte_nonzero_count: 0,
                trailing_byte_distinct_value_count: 1,
                trailing_byte_sample_values_hex: vec!["0x00".to_string()],
                best_probable_density_lane_relative_offset_hex: Some("0x24".to_string()),
            }],
            evidence: vec![],
        });
    report.save_placed_structure_record_triplet_probe =
        Some(SmpSavePlacedStructureRecordTripletProbe {
            profile_family: "rt3-classic-save-container-v1".to_string(),
            source_kind: "save-placed-structure-record-triplets".to_string(),
            semantic_family: "scenario-save-placed-structure-record-triplets".to_string(),
            records_tag_offset: 0x3600,
            close_tag_offset: 0x3800,
            record_count: 2,
            entries: vec![
                SmpSavePlacedStructureRecordTripletEntryProbe {
                    record_index: 0,
                    primary_name: "FarmCorn".to_string(),
                    secondary_name: "FarmSet".to_string(),
                    name_tag_relative_offset: 0,
                    policy_tag_relative_offset: 0x10,
                    profile_tag_relative_offset: 0x2e,
                    policy_chunk_len: 0x1a,
                    profile_chunk_len: 0x10,
                    policy_f32_lane_0: 1.0,
                    policy_f32_lane_1: 2.0,
                    policy_f32_lane_2: 3.0,
                    policy_f32_lane_3: 4.0,
                    policy_f32_lane_4: 5.0,
                    policy_reserved_dword: 0,
                    policy_trailing_word: 1,
                    policy_trailing_word_hex: "0x0001".to_string(),
                    profile_open_marker: 0x00005dc1,
                    profile_open_marker_hex: "0x00005dc1".to_string(),
                    profile_repeated_primary_name: "FarmCorn".to_string(),
                    profile_repeated_secondary_name: "FarmSet".to_string(),
                    profile_footer_relative_offset: 0x08,
                    profile_footer_relative_offset_hex: "0x8".to_string(),
                    profile_pre_footer_padding_len: 1,
                    profile_pre_footer_padding_hex_bytes: vec!["0x00".to_string()],
                    profile_companion_byte_u8: Some(0),
                    profile_companion_byte_hex: Some("0x00".to_string()),
                    profile_payload_dword: 0,
                    profile_payload_dword_hex: "0x00000000".to_string(),
                    profile_sentinel_i32: 4,
                    profile_status_kind: "farm_growth_stage_bucket".to_string(),
                    farm_growth_stage_index: Some(4),
                    profile_close_marker: 0x00005dc2,
                    profile_close_marker_hex: "0x00005dc2".to_string(),
                },
                SmpSavePlacedStructureRecordTripletEntryProbe {
                    record_index: 1,
                    primary_name: "StationA".to_string(),
                    secondary_name: "StationSetA".to_string(),
                    name_tag_relative_offset: 0x40,
                    policy_tag_relative_offset: 0x50,
                    profile_tag_relative_offset: 0x6e,
                    policy_chunk_len: 0x1a,
                    profile_chunk_len: 0x10,
                    policy_f32_lane_0: 0.0,
                    policy_f32_lane_1: 0.0,
                    policy_f32_lane_2: 0.0,
                    policy_f32_lane_3: 0.0,
                    policy_f32_lane_4: 0.0,
                    policy_reserved_dword: 0,
                    policy_trailing_word: 1,
                    policy_trailing_word_hex: "0x0001".to_string(),
                    profile_open_marker: 0x00005dc1,
                    profile_open_marker_hex: "0x00005dc1".to_string(),
                    profile_repeated_primary_name: "StationA".to_string(),
                    profile_repeated_secondary_name: "StationSetA".to_string(),
                    profile_footer_relative_offset: 0x08,
                    profile_footer_relative_offset_hex: "0x8".to_string(),
                    profile_pre_footer_padding_len: 1,
                    profile_pre_footer_padding_hex_bytes: vec!["0x07".to_string()],
                    profile_companion_byte_u8: Some(7),
                    profile_companion_byte_hex: Some("0x07".to_string()),
                    profile_payload_dword: 0x00005dc1,
                    profile_payload_dword_hex: "0x00005dc1".to_string(),
                    profile_sentinel_i32: 0,
                    profile_status_kind: "opaque_nondefault".to_string(),
                    farm_growth_stage_index: None,
                    profile_close_marker: 0x00005dc2,
                    profile_close_marker_hex: "0x00005dc2".to_string(),
                },
            ],
            evidence: vec![],
        });
    report.save_placed_structure_dynamic_side_buffer_probe =
        Some(SmpSavePlacedStructureDynamicSideBufferProbe {
            profile_family: "rt3-classic-save-container-v1".to_string(),
            source_kind: "save-placed-structure-dynamic-side-buffer-records".to_string(),
            semantic_family: "scenario-save-placed-structure-dynamic-side-buffer-records"
                .to_string(),
            metadata_tag_offset: 0x3800,
            records_tag_offset: 0x3900,
            close_tag_offset: 0x3d00,
            records_span_len: 0x400,
            direct_record_stride: 6,
            direct_record_stride_hex: "0x6".to_string(),
            live_id_bound: 0x80,
            live_id_bound_hex: "0x00000080".to_string(),
            live_record_count: 118,
            live_record_count_hex: "0x00000076".to_string(),
            owner_shared_dword: 0xff0000ff,
            owner_shared_dword_hex: "0xff0000ff".to_string(),
            owner_shared_dword_relative_offset: 0,
            owner_shared_dword_matches_first_compact_prefix_leading_dword: true,
            first_record_child_count_after_owner_shared: Some(1),
            first_record_child_count_after_owner_shared_hex: Some("0x0001".to_string()),
            first_record_saved_primary_child_byte_after_owner_shared: Some(0xff),
            first_record_saved_primary_child_byte_after_owner_shared_hex: Some("0xff".to_string()),
            first_record_first_name_tag_relative_offset_after_owner_shared: Some(3),
            prefix_leading_dword: 0xff0000ff,
            prefix_leading_dword_hex: "0xff0000ff".to_string(),
            prefix_trailing_word: 1,
            prefix_trailing_word_hex: "0x0001".to_string(),
            prefix_separator_byte: 0xff,
            prefix_separator_byte_hex: "0xff".to_string(),
            first_embedded_name_tag_relative_offset: 3,
            embedded_name_tag_count: 118,
            decoded_embedded_name_row_count: 118,
            decoded_embedded_name_row_with_tertiary_name_count: 0,
            unique_compact_prefix_pattern_count: 4,
            prefix_leading_dword_matching_embedded_profile_tag_count: 0,
            unique_embedded_name_pair_count: 9,
            first_embedded_primary_name: Some("StationA".to_string()),
            first_embedded_secondary_name: Some("StationSetA".to_string()),
            first_embedded_tertiary_name: None,
            embedded_name_row_samples: vec![],
            compact_prefix_pattern_summaries: vec![
                SmpSavePlacedStructureDynamicSideBufferPrefixPatternSummary {
                    prefix_leading_dword: 0xff0000ff,
                    prefix_leading_dword_hex: "0xff0000ff".to_string(),
                    prefix_trailing_word: 1,
                    prefix_trailing_word_hex: "0x0001".to_string(),
                    prefix_separator_byte: 0xff,
                    prefix_separator_byte_hex: "0xff".to_string(),
                    count: 62,
                    first_name_tag_relative_offset: 3,
                    prefix_leading_dword_matches_embedded_profile_tag: false,
                    section_like_primary_name_count: 12,
                    cap_like_primary_name_count: 21,
                    other_primary_name_count: 29,
                    first_primary_name: Some("StationA".to_string()),
                    first_secondary_name: Some("StationSetA".to_string()),
                },
            ],
            name_pair_summaries: vec![SmpSavePlacedStructureDynamicSideBufferNamePairSummary {
                primary_name: "StationA".to_string(),
                secondary_name: "StationSetA".to_string(),
                count: 14,
                first_name_tag_relative_offset: 3,
                unique_compact_prefix_pattern_count: 1,
                dominant_prefix_leading_dword: 0xff0000ff,
                dominant_prefix_leading_dword_hex: "0xff0000ff".to_string(),
                dominant_prefix_trailing_word: 1,
                dominant_prefix_trailing_word_hex: "0x0001".to_string(),
                dominant_prefix_separator_byte: 0xff,
                dominant_prefix_separator_byte_hex: "0xff".to_string(),
                dominant_prefix_count: 14,
            }],
            payload_envelope_summary: None,
            live_entry_prelude_summary: None,
            evidence: vec![],
        });
    let slice = load_save_slice_from_report(&report).expect("classic save slice");
    let region_collection = slice
        .region_collection
        .expect("region collection should project");
    assert_eq!(region_collection.source_kind, "save-region-record-triplets");
    assert_eq!(region_collection.observed_entry_count, 2);
    assert_eq!(region_collection.entries[0].name, "Marker09");
    assert_eq!(region_collection.entries[1].pre_name_prefix_len, 8);
    assert_eq!(
        region_collection.entries[1].policy_reserved_dwords,
        vec![0, 4, 0]
    );
    assert_eq!(
        region_collection.entries[0]
            .profile_collection
            .as_ref()
            .map(|collection| collection.entries.len()),
        Some(2)
    );
    let region_fixed_row_run_summary = slice
        .region_fixed_row_run_summary
        .expect("region fixed-row summary should project");
    assert_eq!(
        region_fixed_row_run_summary.source_kind,
        "save-region-fixed-row-run-candidates"
    );
    assert_eq!(region_fixed_row_run_summary.candidates.len(), 1);
    assert_eq!(
        region_fixed_row_run_summary.candidates[0].rows_offset_hex,
        "0x5310"
    );
    let collection = slice
        .placed_structure_collection
        .expect("placed structure collection should project");
    assert_eq!(
        collection.source_kind,
        "save-placed-structure-record-triplets"
    );
    assert_eq!(collection.observed_entry_count, 2);
    assert_eq!(collection.entries[0].primary_name, "FarmCorn");
    assert_eq!(collection.entries[0].farm_growth_stage_index, Some(4));
    assert_eq!(collection.entries[1].profile_companion_byte_u8, Some(7));
    let side_buffer_summary = slice
        .placed_structure_dynamic_side_buffer_summary
        .expect("side-buffer summary should project");
    assert_eq!(
        side_buffer_summary.source_kind,
        "save-placed-structure-dynamic-side-buffer-records"
    );
    assert_eq!(side_buffer_summary.observed_entry_count, 118);
    assert_eq!(side_buffer_summary.unique_embedded_name_pair_count, 9);
    assert_eq!(side_buffer_summary.triplet_alignment_overlap_count, 1);
    assert_eq!(
        side_buffer_summary.triplet_alignment_side_buffer_only_name_pair_count,
        0
    );
    assert!(slice.notes.iter().any(|line| {
        line.contains("loaded region triplet rows as first-class context")
            && line.contains("3 embedded profile rows")
    }));
    assert!(slice.notes.iter().any(|line| {
        line.contains("region fixed-row run summary") && line.contains("Some(\"0x5310\")")
    }));
    assert!(slice.notes.iter().any(|line| {
        line.contains("placed-structure triplet rows as first-class context") && line.contains("2")
    }));
    assert!(slice.notes.iter().any(|line| {
        line.contains("placed-structure dynamic side-buffer summary")
            && line.contains("118 decoded name rows")
    }));
}

#[test]
fn loads_rt3_105_save_slice_from_report() {
    let mut report = inspect_smp_bytes(&[]);
    let packed_profile = SmpRt3105PackedProfileProbe {
        profile_family: "rt3-105-save-container-v1".to_string(),
        packed_profile_offset: 0x73c0,
        packed_profile_len: 0x108,
        packed_profile_len_hex: "0x108".to_string(),
        packed_profile_block: SmpRt3105PackedProfileBlock {
            relative_len: 0x108,
            relative_len_hex: "0x108".to_string(),
            leading_word_0: 3,
            leading_word_0_hex: "0x00000003".to_string(),
            trailing_zero_word_count_after_leading_word: 2,
            header_flag_word_3: 1,
            header_flag_word_3_hex: "0x00000001".to_string(),
            map_path_offset: 0x10,
            map_path: Some("Alternate USA.gmp".to_string()),
            display_name_offset: 0x43,
            display_name: Some("Alternate USA".to_string()),
            profile_byte_0x77: 0x07,
            profile_byte_0x77_hex: "0x07".to_string(),
            profile_byte_0x82: 0x4d,
            profile_byte_0x82_hex: "0x4d".to_string(),
            profile_byte_0x97: 0,
            profile_byte_0x97_hex: "0x00".to_string(),
            profile_byte_0xc5: 0,
            profile_byte_0xc5_hex: "0x00".to_string(),
            stable_nonzero_words: vec![],
        },
        ascii_runs: vec![],
    };
    let name_table = SmpRt3105SaveNameTableProbe {
        profile_family: "rt3-105-save-container-v1".to_string(),
        source_kind: "save-bridge-secondary-block".to_string(),
        semantic_family: "scenario-named-candidate-availability-table".to_string(),
        semantic_alignment: vec![],
        header_offset: 0x6a70,
        header_word_0: 0,
        header_word_0_hex: "0x00000000".to_string(),
        header_word_1: 0,
        header_word_1_hex: "0x00000000".to_string(),
        header_word_2: 0x332e,
        header_word_2_hex: "0x0000332e".to_string(),
        entry_stride: 0x22,
        entry_stride_hex: "0x22".to_string(),
        header_prefix_word_count: 11,
        observed_entry_capacity: 0x44,
        observed_entry_count: 2,
        zero_trailer_entry_count: 1,
        nonzero_trailer_entry_count: 1,
        distinct_trailer_words: vec![0, 1],
        distinct_trailer_hex_words: vec!["0x00000000".to_string(), "0x00000001".to_string()],
        zero_trailer_entry_names: vec!["Uranium Mine".to_string()],
        entries_offset: 0x6ad1,
        entries_end_offset: 0x6b15,
        trailing_footer_hex: "dc3200001437000000".to_string(),
        footer_progress_word_0: 0x32dc,
        footer_progress_word_0_hex: "0x000032dc".to_string(),
        footer_progress_word_1: 0x3714,
        footer_progress_word_1_hex: "0x00003714".to_string(),
        footer_trailing_byte: 0,
        footer_trailing_byte_hex: "0x00".to_string(),
        footer_grounded_alignments: vec![],
        entries: vec![
            SmpRt3105SaveNameTableEntry {
                index: 0,
                offset: 0x6ad1,
                text: "AutoPlant".to_string(),
                availability_dword: 1,
                availability_dword_hex: "0x00000001".to_string(),
                trailer_word: 1,
                trailer_word_hex: "0x00000001".to_string(),
            },
            SmpRt3105SaveNameTableEntry {
                index: 1,
                offset: 0x6af3,
                text: "Uranium Mine".to_string(),
                availability_dword: 0,
                availability_dword_hex: "0x00000000".to_string(),
                trailer_word: 0,
                trailer_word_hex: "0x00000000".to_string(),
            },
        ],
        evidence: vec![],
    };
    let named_locomotive_table = SmpRt3105SaveNamedLocomotiveAvailabilityProbe {
        profile_family: "rt3-105-save-container-v1".to_string(),
        source_kind: "save-direct-locomotive-row-run".to_string(),
        semantic_family: "scenario-named-locomotive-availability-table".to_string(),
        semantic_alignment: vec![],
        entries_offset: 0x7c78,
        entry_stride: RT3_105_SAVE_NAMED_LOCOMOTIVE_ENTRY_STRIDE,
        entry_stride_hex: format!("0x{:x}", RT3_105_SAVE_NAMED_LOCOMOTIVE_ENTRY_STRIDE),
        observed_entry_count: 2,
        zero_availability_count: 1,
        zero_availability_names: vec!["Big Boy".to_string()],
        entries_end_offset: 0x7c78 + 2 * RT3_105_SAVE_NAMED_LOCOMOTIVE_ENTRY_STRIDE,
        entries: vec![
            SmpRt3105SaveNameTableEntry {
                index: 0,
                offset: 0x7c78,
                text: "Big Boy".to_string(),
                availability_dword: 0,
                availability_dword_hex: "0x00000000".to_string(),
                trailer_word: 0,
                trailer_word_hex: "0x00000000".to_string(),
            },
            SmpRt3105SaveNameTableEntry {
                index: 1,
                offset: 0x7cb9,
                text: "GP7".to_string(),
                availability_dword: 1,
                availability_dword_hex: "0x00000001".to_string(),
                trailer_word: 1,
                trailer_word_hex: "0x00000001".to_string(),
            },
        ],
        evidence: vec![],
    };
    let bridge = SmpRt3105PostSpanBridgeProbe {
        profile_family: "rt3-105-save-container-v1".to_string(),
        bridge_family: "rt3-105-save-post-span-bridge-v1".to_string(),
        bridge_evidence: vec![],
        span_target_offset: 0x3678,
        next_candidate_offset: Some(0x4f14),
        next_candidate_delta_from_span_target: Some(0x189c),
        packed_profile_offset: 0x73c0,
        packed_profile_delta_from_span_target: 0x3d48,
        next_candidate_delta_from_packed_profile: Some(-0x24ac),
        selector_high_u16: 0x7110,
        selector_high_hex: "0x7110".to_string(),
        descriptor_high_u16: 0x7801,
        descriptor_high_hex: "0x7801".to_string(),
        next_candidate_high_u16_words: vec![0x6200, 0x0000, 0xfff7, 0x5515],
        next_candidate_high_hex_words: vec![],
    };
    report.rt3_105_packed_profile_probe = Some(packed_profile.clone());
    report.rt3_105_save_name_table_probe = Some(name_table.clone());
    report.rt3_105_save_named_locomotive_availability_probe = Some(named_locomotive_table.clone());
    report.save_load_summary = build_save_load_summary(
        Some("gms"),
        Some(&SmpContainerProfile {
            profile_family: "rt3-105-save-container-v1".to_string(),
            profile_evidence: vec![],
            is_known_profile: true,
        }),
        None,
        Some(&bridge),
        None,
        Some(&packed_profile),
        Some(&name_table),
    );

    let slice = load_save_slice_from_report(&report).expect("1.05 save slice");
    assert_eq!(slice.mechanism_family, "rt3-105-save-post-span-bridge-v1");
    assert_eq!(
        slice
            .profile
            .as_ref()
            .and_then(|profile| profile.map_path.as_deref()),
        Some("Alternate USA.gmp")
    );
    assert_eq!(
        slice
            .candidate_availability_table
            .as_ref()
            .expect("candidate table")
            .entries[1]
            .text,
        "Uranium Mine"
    );
    assert_eq!(
        slice
            .named_locomotive_availability_table
            .as_ref()
            .expect("named locomotive availability table")
            .entries[1]
            .text,
        "GP7"
    );
    assert_eq!(
        slice
            .locomotive_catalog
            .as_ref()
            .expect("derived locomotive catalog")
            .entries[0]
            .name,
        "Big Boy"
    );
    assert_eq!(
        slice
            .locomotive_catalog
            .as_ref()
            .expect("derived locomotive catalog")
            .entries[1]
            .locomotive_id,
        2
    );
}
