use super::super::super::*;

pub(in crate::inspect::smp) struct FirstRecordNamePrelude {
    pub(in crate::inspect::smp) owner_shared_dword: u32,
    pub(in crate::inspect::smp) owner_shared_dword_relative_offset: usize,
    pub(in crate::inspect::smp) first_record_child_count_after_owner_shared: Option<u16>,
    pub(in crate::inspect::smp) first_record_saved_primary_child_byte_after_owner_shared:
        Option<u8>,
    pub(in crate::inspect::smp) first_record_first_name_tag_relative_offset_after_owner_shared:
        Option<usize>,
    pub(in crate::inspect::smp) prefix_leading_dword: u32,
    pub(in crate::inspect::smp) prefix_trailing_word: u16,
    pub(in crate::inspect::smp) prefix_separator_byte: u8,
    pub(in crate::inspect::smp) first_embedded_primary_name: String,
    pub(in crate::inspect::smp) first_embedded_secondary_name: String,
    pub(in crate::inspect::smp) first_embedded_tertiary_name: Option<String>,
}

pub(in crate::inspect::smp) fn parse_first_record_name_prelude(
    records_payload: &[u8],
    first_embedded_name_tag_relative_offset: usize,
) -> Option<FirstRecordNamePrelude> {
    let prefix_payload = records_payload.get(..first_embedded_name_tag_relative_offset)?;
    if prefix_payload.len() < 7 {
        return None;
    }
    let owner_shared_dword = read_u32_at(prefix_payload, 0)?;
    let owner_shared_dword_relative_offset = 0usize;
    let first_record_child_count_after_owner_shared = read_u16_at(records_payload, 4);
    let first_record_saved_primary_child_byte_after_owner_shared = read_u8_at(records_payload, 6);
    let first_record_first_name_tag_relative_offset_after_owner_shared =
        (3usize..=16usize).find(|offset| {
            read_u16_at(records_payload, 4 + *offset) == Some(SAVE_REGION_RECORD_NAME_TAG)
        });
    let prefix_leading_dword = owner_shared_dword;
    let prefix_trailing_word = read_u16_at(prefix_payload, 4)?;
    let prefix_separator_byte = prefix_payload.get(6).copied()?;
    let mut parsed_embedded_names = None;
    for relative_name_offset in [4usize, 6usize] {
        let Some(name_payload) =
            records_payload.get(first_embedded_name_tag_relative_offset + relative_name_offset..)
        else {
            continue;
        };
        if let Some(names) = parse_save_len_prefixed_ascii_name_triplet(name_payload) {
            parsed_embedded_names = Some(names);
            break;
        }
    }
    let (first_embedded_primary_name, first_embedded_secondary_name, first_embedded_tertiary_name) =
        parsed_embedded_names?;
    Some(FirstRecordNamePrelude {
        owner_shared_dword,
        owner_shared_dword_relative_offset,
        first_record_child_count_after_owner_shared,
        first_record_saved_primary_child_byte_after_owner_shared,
        first_record_first_name_tag_relative_offset_after_owner_shared,
        prefix_leading_dword,
        prefix_trailing_word,
        prefix_separator_byte,
        first_embedded_primary_name,
        first_embedded_secondary_name,
        first_embedded_tertiary_name,
    })
}
