use crate::inspect::smp::bundle::{
    SmpContainerProfile, SmpRuntimeAnchorCycleBlock, SmpRuntimeTrailerBlock,
};

pub(in crate::inspect::smp) fn parse_runtime_trailer_block(
    container_profile: Option<&SmpContainerProfile>,
    runtime_anchor_cycle_block: Option<&SmpRuntimeAnchorCycleBlock>,
) -> Option<SmpRuntimeTrailerBlock> {
    let profile = container_profile?;
    let anchor = runtime_anchor_cycle_block?;
    let words = &anchor.trailer_words;
    if words.len() < 16 {
        return None;
    }

    let trailer_family = match profile.profile_family.as_str() {
        "rt3-classic-save-container-v1"
            if words[..6]
                == [
                    0x00020000, 0x00030000, 0x00010000, 0x00010000, 0x00010000, 0x00020000,
                ] =>
        {
            "rt3-classic-save-trailer-v1"
        }
        "rt3-classic-sandbox-container-v1"
            if words[..6]
                == [
                    0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000,
                ] =>
        {
            "rt3-classic-sandbox-trailer-v1"
        }
        "rt3-105-save-container-v1"
        | "rt3-105-scenario-save-container-v1"
        | "rt3-105-alt-save-container-v1"
            if words[..6]
                == [
                    0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000,
                ] =>
        {
            "rt3-105-save-trailer-v1"
        }
        "rt3-105-sandbox-container-v1"
            if words[..6]
                == [
                    0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000,
                ] =>
        {
            "rt3-105-sandbox-trailer-v1"
        }
        _ => "unknown",
    }
    .to_string();

    let tag_chunk_id_u16 = (words[6] >> 16) as u16;
    let length_high_u16 = (words[7] >> 16) as u16;
    let selector_high_u16 = (words[8] >> 16) as u16;
    let descriptor_high_u16 = (words[10] >> 16) as u16;
    let tag_chunk_id_grounded_alignment =
        classify_runtime_trailer_chunk_id_grounded_alignment(tag_chunk_id_u16).map(str::to_string);

    let mut trailer_evidence = vec![
        format!("container profile {}", profile.profile_family),
        format!(
            "prefix words {}",
            words[..6]
                .iter()
                .map(|word| format!("0x{word:08x}"))
                .collect::<Vec<_>>()
                .join(", ")
        ),
        format!("high-16 chunk id 0x{tag_chunk_id_u16:04x} from trailer word 6"),
        format!("high-16 span 0x{length_high_u16:04x} from trailer word 7"),
        format!("high-16 selector 0x{selector_high_u16:04x} from trailer word 8"),
        format!("high-16 descriptor 0x{descriptor_high_u16:04x} from trailer word 10"),
    ];
    if let Some(alignment) = &tag_chunk_id_grounded_alignment {
        trailer_evidence.push(alignment.clone());
    }

    Some(SmpRuntimeTrailerBlock {
        profile_family: profile.profile_family.clone(),
        trailer_family,
        trailer_evidence,
        trailer_offset: anchor.trailer_offset,
        prefix_words_0_to_5: words[..6].to_vec(),
        prefix_hex_words_0_to_5: words[..6]
            .iter()
            .map(|word| format!("0x{word:08x}"))
            .collect(),
        tag_word_6: words[6],
        tag_word_6_hex: format!("0x{:08x}", words[6]),
        tag_chunk_id_u16,
        tag_chunk_id_hex: format!("0x{tag_chunk_id_u16:04x}"),
        tag_chunk_id_grounded_alignment,
        length_word_7: words[7],
        length_word_7_hex: format!("0x{:08x}", words[7]),
        length_high_u16,
        length_high_hex: format!("0x{length_high_u16:04x}"),
        selector_word_8: words[8],
        selector_word_8_hex: format!("0x{:08x}", words[8]),
        selector_high_u16,
        selector_high_hex: format!("0x{selector_high_u16:04x}"),
        layout_word_9: words[9],
        layout_word_9_hex: format!("0x{:08x}", words[9]),
        descriptor_word_10: words[10],
        descriptor_word_10_hex: format!("0x{:08x}", words[10]),
        descriptor_high_u16,
        descriptor_high_hex: format!("0x{descriptor_high_u16:04x}"),
        descriptor_word_11: words[11],
        descriptor_word_11_hex: format!("0x{:08x}", words[11]),
        counter_word_12: words[12],
        counter_word_12_hex: format!("0x{:08x}", words[12]),
        offset_word_13: words[13],
        offset_word_13_hex: format!("0x{:08x}", words[13]),
        span_word_14: words[14],
        span_word_14_hex: format!("0x{:08x}", words[14]),
        mode_word_15: words[15],
        mode_word_15_hex: format!("0x{:08x}", words[15]),
        words: words.to_vec(),
        hex_words: words.iter().map(|word| format!("0x{word:08x}")).collect(),
    })
}

pub(in crate::inspect::smp) fn classify_runtime_trailer_chunk_id_grounded_alignment(
    tag_chunk_id_u16: u16,
) -> Option<&'static str> {
    match tag_chunk_id_u16 {
        0x2ee1 => Some(
            "High-16 chunk id 0x2ee1 matches the disassembly-grounded map-style bundle family already read by shell_setup_load_selected_profile_bundle_into_payload_record.",
        ),
        _ => None,
    }
}
