use serde::{Deserialize, Serialize};

use crate::inspect::smp::structures::{
    SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSummary,
    SmpSavePlacedStructureDynamicSideBufferNamePairSummary,
    SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSummary,
    SmpSavePlacedStructureDynamicSideBufferPrefixPatternSummary,
    SmpSavePlacedStructureDynamicSideBufferSampleEntry,
};

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferProbe {
    pub profile_family: String,
    pub source_kind: String,
    pub semantic_family: String,
    pub metadata_tag_offset: usize,
    pub records_tag_offset: usize,
    pub close_tag_offset: usize,
    pub records_span_len: usize,
    pub direct_record_stride: u32,
    pub direct_record_stride_hex: String,
    pub live_id_bound: u32,
    pub live_id_bound_hex: String,
    pub live_record_count: u32,
    pub live_record_count_hex: String,
    pub owner_shared_dword: u32,
    pub owner_shared_dword_hex: String,
    pub owner_shared_dword_relative_offset: usize,
    pub owner_shared_dword_matches_first_compact_prefix_leading_dword: bool,
    #[serde(default)]
    pub first_record_child_count_after_owner_shared: Option<u16>,
    #[serde(default)]
    pub first_record_child_count_after_owner_shared_hex: Option<String>,
    #[serde(default)]
    pub first_record_saved_primary_child_byte_after_owner_shared: Option<u8>,
    #[serde(default)]
    pub first_record_saved_primary_child_byte_after_owner_shared_hex: Option<String>,
    #[serde(default)]
    pub first_record_first_name_tag_relative_offset_after_owner_shared: Option<usize>,
    pub prefix_leading_dword: u32,
    pub prefix_leading_dword_hex: String,
    pub prefix_trailing_word: u16,
    pub prefix_trailing_word_hex: String,
    pub prefix_separator_byte: u8,
    pub prefix_separator_byte_hex: String,
    pub first_embedded_name_tag_relative_offset: usize,
    pub embedded_name_tag_count: usize,
    pub decoded_embedded_name_row_count: usize,
    pub decoded_embedded_name_row_with_tertiary_name_count: usize,
    pub unique_compact_prefix_pattern_count: usize,
    pub prefix_leading_dword_matching_embedded_profile_tag_count: usize,
    pub unique_embedded_name_pair_count: usize,
    #[serde(default)]
    pub first_embedded_primary_name: Option<String>,
    #[serde(default)]
    pub first_embedded_secondary_name: Option<String>,
    #[serde(default)]
    pub first_embedded_tertiary_name: Option<String>,
    #[serde(default)]
    pub embedded_name_row_samples: Vec<SmpSavePlacedStructureDynamicSideBufferSampleEntry>,
    #[serde(default)]
    pub compact_prefix_pattern_summaries:
        Vec<SmpSavePlacedStructureDynamicSideBufferPrefixPatternSummary>,
    #[serde(default)]
    pub name_pair_summaries: Vec<SmpSavePlacedStructureDynamicSideBufferNamePairSummary>,
    #[serde(default)]
    pub payload_envelope_summary:
        Option<SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSummary>,
    #[serde(default)]
    pub live_entry_prelude_summary:
        Option<SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSummary>,
    pub evidence: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedPlacedStructureDynamicSideBufferSummary {
    pub source_kind: String,
    pub semantic_family: String,
    pub observed_entry_count: u32,
    pub owner_shared_dword_hex: String,
    pub unique_embedded_name_pair_count: usize,
    pub decoded_embedded_name_row_count: usize,
    pub first_prefix_leading_dword_hex: String,
    pub first_prefix_trailing_word_hex: String,
    pub first_prefix_separator_byte_hex: String,
    pub triplet_alignment_overlap_count: usize,
    pub triplet_alignment_side_buffer_only_name_pair_count: usize,
    #[serde(default)]
    pub compact_prefix_pattern_summaries:
        Vec<SmpSavePlacedStructureDynamicSideBufferPrefixPatternSummary>,
    #[serde(default)]
    pub name_pair_summaries: Vec<SmpSavePlacedStructureDynamicSideBufferNamePairSummary>,
}
