use serde::{Deserialize, Serialize};

use crate::inspect::smp::structures::SmpSavePlacedStructureDynamicSideBufferDominantProfileSpanNamePairSummary;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidateSummary {
    pub row_count_with_candidate_window: usize,
    pub unique_candidate_pattern_count: usize,
    #[serde(default)]
    pub dominant_child_count_candidate: Option<u16>,
    pub dominant_child_count_candidate_count: usize,
    #[serde(default)]
    pub dominant_saved_primary_child_byte_candidate: Option<u8>,
    #[serde(default)]
    pub dominant_saved_primary_child_byte_candidate_hex: Option<String>,
    pub dominant_saved_primary_child_byte_candidate_count: usize,
    #[serde(default)]
    pub dominant_candidate_pattern:
        Option<SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePattern>,
    #[serde(default)]
    pub candidate_pattern_correlations:
        Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePatternCorrelation>,
    #[serde(default)]
    pub profile_span_correlations:
        Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeProfileSpanCorrelation>,
    #[serde(default)]
    pub compact_prefix_correlations:
        Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixCorrelation>,
    #[serde(default)]
    pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidateSample>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePattern {
    pub child_count_candidate: u16,
    pub child_count_candidate_hex: String,
    pub saved_primary_child_byte_candidate: u8,
    pub saved_primary_child_byte_candidate_hex: String,
    pub count: usize,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidateSample {
    pub sample_index: usize,
    pub name_tag_relative_offset: usize,
    #[serde(default)]
    pub primary_name: Option<String>,
    #[serde(default)]
    pub secondary_name: Option<String>,
    pub child_count_candidate: u16,
    pub child_count_candidate_hex: String,
    pub saved_primary_child_byte_candidate: u8,
    pub saved_primary_child_byte_candidate_hex: String,
    #[serde(default)]
    pub previous_profile_chunk_len_to_next_name_or_end: Option<usize>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixCorrelation {
    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 row_count: usize,
    pub unique_name_pair_count: usize,
    pub unique_profile_span_count: usize,
    #[serde(default)]
    pub dominant_primary_name: Option<String>,
    #[serde(default)]
    pub dominant_secondary_name: Option<String>,
    pub dominant_name_pair_count: usize,
    #[serde(default)]
    pub dominant_profile_span: Option<usize>,
    pub dominant_profile_span_count: usize,
    #[serde(default)]
    pub dominant_candidate_pattern:
        Option<SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePattern>,
    #[serde(default)]
    pub dominant_mode_family: Option<String>,
    pub dominant_mode_family_count: usize,
    #[serde(default)]
    pub mode_family_counts: Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeModeFamilyCount>,
    #[serde(default)]
    pub name_pair_summaries:
        Vec<SmpSavePlacedStructureDynamicSideBufferDominantProfileSpanNamePairSummary>,
    #[serde(default)]
    pub profile_span_counts:
        Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixProfileSpanCount>,
    pub rows_with_previous_short_profile_flag_pair: usize,
    #[serde(default)]
    pub previous_short_profile_flag_pair_counts:
        Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixFlagPairCount>,
    #[serde(default)]
    pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixSample>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixProfileSpanCount {
    pub previous_profile_chunk_len_to_next_name_or_end: usize,
    pub count: usize,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixFlagPairCount {
    pub first_flag_byte: u8,
    pub first_flag_byte_hex: String,
    pub second_flag_byte: u8,
    pub second_flag_byte_hex: String,
    pub count: usize,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCompactPrefixSample {
    pub sample_index: usize,
    pub name_tag_relative_offset: usize,
    #[serde(default)]
    pub primary_name: Option<String>,
    #[serde(default)]
    pub secondary_name: Option<String>,
    pub child_count_candidate: u16,
    pub child_count_candidate_hex: String,
    pub saved_primary_child_byte_candidate: u8,
    pub saved_primary_child_byte_candidate_hex: String,
    #[serde(default)]
    pub previous_profile_chunk_len_to_next_name_or_end: Option<usize>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePatternCorrelation {
    pub child_count_candidate: u16,
    pub child_count_candidate_hex: String,
    pub saved_primary_child_byte_candidate: u8,
    pub saved_primary_child_byte_candidate_hex: String,
    pub row_count: usize,
    pub unique_name_pair_count: usize,
    pub unique_profile_span_count: usize,
    #[serde(default)]
    pub dominant_primary_name: Option<String>,
    #[serde(default)]
    pub dominant_secondary_name: Option<String>,
    pub dominant_name_pair_count: usize,
    #[serde(default)]
    pub dominant_profile_span: Option<usize>,
    pub dominant_profile_span_count: usize,
    #[serde(default)]
    pub dominant_mode_family: Option<String>,
    pub dominant_mode_family_count: usize,
    #[serde(default)]
    pub mode_family_counts: Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeModeFamilyCount>,
    #[serde(default)]
    pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidateSample>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeModeFamilyCount {
    pub mode_family: String,
    pub count: usize,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeProfileSpanCorrelation {
    pub previous_profile_chunk_len_to_next_name_or_end: usize,
    pub row_count: usize,
    #[serde(default)]
    pub dominant_child_count_candidate: Option<u16>,
    pub dominant_child_count_candidate_count: usize,
    #[serde(default)]
    pub dominant_saved_primary_child_byte_candidate: Option<u8>,
    #[serde(default)]
    pub dominant_saved_primary_child_byte_candidate_hex: Option<String>,
    pub dominant_saved_primary_child_byte_candidate_count: usize,
    #[serde(default)]
    pub dominant_candidate_pattern:
        Option<SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePattern>,
    #[serde(default)]
    pub dominant_mode_family: Option<String>,
    pub dominant_mode_family_count: usize,
    #[serde(default)]
    pub mode_family_counts: Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeModeFamilyCount>,
    #[serde(default)]
    pub compact_prefix_pattern_summaries:
        Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeProfileSpanPrefixSummary>,
    #[serde(default)]
    pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeProfileSpanSample>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeProfileSpanPrefixSummary {
    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 count: usize,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferNamePreludeProfileSpanSample {
    pub sample_index: usize,
    pub name_tag_relative_offset: usize,
    #[serde(default)]
    pub primary_name: Option<String>,
    #[serde(default)]
    pub secondary_name: Option<String>,
    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 child_count_candidate: u16,
    pub child_count_candidate_hex: String,
    pub saved_primary_child_byte_candidate: u8,
    pub saved_primary_child_byte_candidate_hex: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSummary {
    pub live_entry_directory_row_count: usize,
    pub decoded_live_entry_id_count: usize,
    pub payload_relative_offset_monotonic: bool,
    pub rows_with_payload_pointer_inside_records_span: usize,
    pub rows_with_zero_child_count: usize,
    pub rows_with_nonzero_child_count: usize,
    pub rows_with_first_name_tag_after_prelude: usize,
    pub rows_with_first_name_tag_at_offset_3: usize,
    #[serde(default)]
    pub unique_child_count_values: Vec<u16>,
    #[serde(default)]
    pub unique_first_name_tag_relative_offsets: Vec<usize>,
    #[serde(default)]
    pub dominant_child_count: Option<u16>,
    pub dominant_child_count_count: usize,
    #[serde(default)]
    pub dominant_saved_primary_child_byte: Option<u8>,
    #[serde(default)]
    pub dominant_saved_primary_child_byte_hex: Option<String>,
    pub dominant_saved_primary_child_byte_count: usize,
    #[serde(default)]
    pub dominant_first_name_tag_relative_offset: Option<usize>,
    pub dominant_first_name_tag_relative_offset_count: usize,
    #[serde(default)]
    pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSample>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferLiveEntryPreludeSample {
    pub sample_index: usize,
    pub live_entry_id: u32,
    pub payload_relative_offset: u32,
    pub payload_relative_offset_hex: String,
    pub payload_relative_to_records: usize,
    pub child_count: u16,
    pub child_count_hex: String,
    pub saved_primary_child_byte: u8,
    pub saved_primary_child_byte_hex: String,
    pub first_payload_dword_hex: String,
    #[serde(default)]
    pub first_name_tag_relative_offset: Option<usize>,
    #[serde(default)]
    pub first_primary_name: Option<String>,
    #[serde(default)]
    pub first_secondary_name: Option<String>,
    #[serde(default)]
    pub first_tertiary_name: Option<String>,
}
