use super::*;

#[test]
fn builds_region_service_trace_report_with_explicit_latch_blockers() {
    let mut analysis = empty_analysis_report();
    analysis.region_record_triplets = Some(SmpSaveRegionRecordTripletProbe {
        profile_family: analysis.profile_family.clone(),
        source_kind: "save-region-record-triplets".to_string(),
        semantic_family: "marker09".to_string(),
        records_tag_offset: 0,
        close_tag_offset: 0,
        record_count: 1,
        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: 0,
            profile_tag_relative_offset: 0,
            pre_name_prefix_len: 0,
            pre_name_prefix_hex_bytes: Vec::new(),
            pre_name_prefix_dword_candidates: Vec::new(),
            policy_chunk_len: 0,
            profile_chunk_len: 0,
            policy_leading_f32_0: 368.0,
            policy_leading_f32_1: 0.0,
            policy_leading_f32_2: 92.0,
            policy_reserved_dwords: Vec::new(),
            policy_reserved_dword_candidates: Vec::new(),
            policy_trailing_word: 0,
            policy_trailing_word_hex: "0x0000".to_string(),
            profile_collection: Some(SmpSaveRegionProfileCollectionProbe {
                direct_collection_flag: 1,
                entry_stride: 0x22,
                live_id_bound: 17,
                live_record_count: 17,
                entry_start_relative_offset: 0,
                trailing_padding_len: 0,
                entries: Vec::new(),
            }),
        }],
        evidence: Vec::new(),
    });

    let trace = build_region_service_trace_report(&analysis);
    assert_eq!(trace.region_record_triplet_count, 1);
    assert_eq!(trace.queued_notice_record_count, 0);
    assert!(!trace.atlas_candidate_consumers.is_empty());
    assert_eq!(trace.known_owner_bridge_fields.len(), 6);
    assert_eq!(trace.known_bridge_helpers.len(), 16);
    assert_eq!(trace.next_owner_questions.len(), 5);
    assert_eq!(trace.candidate_consumer_hypotheses.len(), 6);
    assert_eq!(
        trace.candidate_consumer_hypotheses[0].status,
        "highest_priority_static_mapping_target"
    );
    assert_eq!(
        trace.candidate_consumer_hypotheses[2].status,
        "secondary_candidate_after_pending_service"
    );
    assert_eq!(
        trace.candidate_consumer_hypotheses[3].status,
        "next_global_restore_handoff_target"
    );
    assert_eq!(
        trace.candidate_consumer_hypotheses[1].status,
        "parallel_static_mapping_target"
    );
    assert!(
        trace.candidate_consumer_hypotheses[1]
            .evidence
            .iter()
            .any(|line| line.contains("0x5209")
                && line.contains("0x520a")
                && line.contains("0x520b"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[1]
            .evidence
            .iter()
            .any(|line| line.contains("0x0041f5c0")
                && line.contains("[region+0x37f]")
                && line.contains("[region+0x385]"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[1]
            .evidence
            .iter()
            .any(|line| line.contains("0x00444887")
                && line.contains("0x00487c20")
                && line.contains("0x0040b5d0"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[1]
            .evidence
            .iter()
            .any(|line| line.contains("0x00421ce0") && line.contains("0x0041fb00"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[1]
            .evidence
            .iter()
            .any(|line| line.contains("0x00421730")
                && line.contains("[region+0x242/+0x246/+0x24a/+0x24e/+0x252]"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[1]
            .evidence
            .iter()
            .any(|line| line.contains("0x00448740..0x0044881f")
                && line.contains("0x006cfc9c")
                && line.contains("0x53b070")
                && line.contains("0x00487bd0"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[1]
            .evidence
            .iter()
            .any(|line| line.contains("0x00487de0")
                && line.contains("0x00533cf0")
                && line.contains("0x00536ea0"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[1]
            .evidence
            .iter()
            .any(|line| line.contains("0x0044c4b0")
                && line.contains("0x00455f60")
                && line.contains("bit 0x10"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[3]
            .candidate_consumers
            .iter()
            .any(|line| line.contains("0x00444887"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[3]
            .candidate_consumers
            .iter()
            .any(|line| line.contains("0x00487c20"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[3]
            .candidate_consumers
            .iter()
            .any(|line| line.contains("0x0040b5d0"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[3]
            .evidence
            .iter()
            .any(|line| line.contains("0x00444887") && line.contains("0x00421510"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[3]
            .evidence
            .iter()
            .any(|line| line.contains("0x00444b90") && line.contains("0x00420560"))
    );
    assert_eq!(
        trace.candidate_consumer_hypotheses[4].status,
        "next_post_load_owner_family"
    );
    assert!(
        trace.candidate_consumer_hypotheses[4]
            .candidate_consumers
            .iter()
            .any(|line| line.contains("0x004384d0"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[4]
            .candidate_consumers
            .iter()
            .any(|line| line.contains("0x004133b0"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[4]
            .candidate_consumers
            .iter()
            .any(|line| line.contains("0x00421c20"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[4]
            .evidence
            .iter()
            .any(|line| line.contains("0x00446d40") && line.contains("0x004384d0"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[4]
            .evidence
            .iter()
            .any(|line| line.contains("0x004133b0") && line.contains("0x00480710"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[4]
            .evidence
            .iter()
            .any(|line| line.contains("0x00421c20") && line.contains("0x004235c0"))
    );
    assert!(
        trace.candidate_consumer_hypotheses[1]
            .evidence
            .iter()
            .any(|line| line.contains("0x004881b0")
                && line.contains("[region+0x3d]")
                && line.contains("[region+0x41]"))
    );
    assert_eq!(trace.entries.len(), 1);
    assert_eq!(
        trace.entries[0].branches[0].status,
        "blocked_missing_pending_bonus_owner_lane"
    );
    assert_eq!(
        trace.entries[0].branches[1].status,
        "blocked_missing_completion_and_one_shot_latches"
    );
    assert!(
        trace
            .notes
            .iter()
            .any(|line| { line.contains("pre-name prefix lengths") && line.contains("[0]") })
    );
}
