use serde::{Deserialize, Serialize};

use crate::inspect::smp::structures::{
    SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePattern,
    SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidateSummary,
    SmpSavePlacedStructureDynamicSideBufferNamePreludeModeFamilyCount,
};

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSummary {
    pub row_count_with_policy_tag_before_next_name: usize,
    pub row_count_with_complete_0x55f1_0x55f2_0x55f3_envelope: usize,
    pub row_count_missing_policy_tag_before_next_name: usize,
    pub row_count_missing_profile_tag_after_policy: usize,
    #[serde(default)]
    pub unique_policy_chunk_lens: Vec<usize>,
    #[serde(default)]
    pub unique_profile_chunk_lens: Vec<usize>,
    #[serde(default)]
    pub dominant_policy_chunk_len: Option<usize>,
    pub dominant_policy_chunk_len_count: usize,
    #[serde(default)]
    pub dominant_profile_chunk_len: Option<usize>,
    pub dominant_profile_chunk_len_count: usize,
    #[serde(default)]
    pub short_profile_flag_pair_summary:
        Option<SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSummary>,
    #[serde(default)]
    pub fixed_policy_summary: Option<SmpSavePlacedStructureDynamicSideBufferFixedPolicySummary>,
    #[serde(default)]
    pub name_prelude_candidate_summary:
        Option<SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidateSummary>,
    #[serde(default)]
    pub dominant_profile_span_class_summary:
        Option<SmpSavePlacedStructureDynamicSideBufferDominantProfileSpanClassSummary>,
    #[serde(default)]
    pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSample>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferDominantProfileSpanClassSummary {
    pub profile_chunk_len_to_next_name_or_end: usize,
    pub row_count: usize,
    pub unique_name_pair_count: usize,
    pub unique_compact_prefix_pattern_count: usize,
    #[serde(default)]
    pub dominant_candidate_pattern:
        Option<SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePattern>,
    #[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_prefix_leading_dword: Option<u32>,
    #[serde(default)]
    pub dominant_prefix_leading_dword_hex: Option<String>,
    #[serde(default)]
    pub dominant_prefix_trailing_word: Option<u16>,
    #[serde(default)]
    pub dominant_prefix_trailing_word_hex: Option<String>,
    #[serde(default)]
    pub dominant_prefix_separator_byte: Option<u8>,
    #[serde(default)]
    pub dominant_prefix_separator_byte_hex: Option<String>,
    pub dominant_prefix_count: usize,
    #[serde(default)]
    pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferDominantProfileSpanSample>,
    #[serde(default)]
    pub name_pair_summaries:
        Vec<SmpSavePlacedStructureDynamicSideBufferDominantProfileSpanNamePairSummary>,
    #[serde(default)]
    pub compact_prefix_pattern_summaries:
        Vec<SmpSavePlacedStructureDynamicSideBufferDominantProfileSpanPrefixSummary>,
    #[serde(default)]
    pub candidate_pattern_summaries:
        Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeCandidatePattern>,
}

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

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferDominantProfileSpanNamePairSummary {
    #[serde(default)]
    pub primary_name: Option<String>,
    #[serde(default)]
    pub secondary_name: Option<String>,
    pub count: usize,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferDominantProfileSpanPrefixSummary {
    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 SmpSavePlacedStructureDynamicSideBufferFixedPolicySummary {
    pub row_count_with_0x1a_policy_chunk: usize,
    pub unique_trailing_word_count: usize,
    #[serde(default)]
    pub dominant_trailing_word: Option<u16>,
    #[serde(default)]
    pub dominant_trailing_word_hex: Option<String>,
    pub dominant_trailing_word_count: usize,
    #[serde(default)]
    pub compact_prefix_correlations:
        Vec<SmpSavePlacedStructureDynamicSideBufferFixedPolicyCompactPrefixCorrelation>,
    #[serde(default)]
    pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferFixedPolicySample>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferFixedPolicySample {
    pub sample_index: usize,
    pub name_tag_relative_offset: usize,
    #[serde(default)]
    pub primary_name: Option<String>,
    #[serde(default)]
    pub secondary_name: Option<String>,
    #[serde(default)]
    pub first_triplet_dwords_hex: Vec<String>,
    #[serde(default)]
    pub second_triplet_dwords_hex: Vec<String>,
    pub trailing_word: u16,
    pub trailing_word_hex: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferFixedPolicyCompactPrefixCorrelation {
    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_policy_tuple_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_mode_family: Option<String>,
    pub dominant_mode_family_count: usize,
    #[serde(default)]
    pub dominant_first_triplet_dwords_hex: Vec<String>,
    #[serde(default)]
    pub dominant_second_triplet_dwords_hex: Vec<String>,
    #[serde(default)]
    pub dominant_trailing_word: Option<u16>,
    #[serde(default)]
    pub dominant_trailing_word_hex: Option<String>,
    pub dominant_policy_tuple_count: usize,
    #[serde(default)]
    pub mode_family_counts: Vec<SmpSavePlacedStructureDynamicSideBufferNamePreludeModeFamilyCount>,
    #[serde(default)]
    pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferFixedPolicySample>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSummary {
    pub row_count_with_0x06_profile_span: usize,
    pub unique_flag_pair_count: usize,
    #[serde(default)]
    pub dominant_first_flag_byte: Option<u8>,
    #[serde(default)]
    pub dominant_first_flag_byte_hex: Option<String>,
    pub dominant_first_flag_byte_count: usize,
    #[serde(default)]
    pub dominant_second_flag_byte: Option<u8>,
    #[serde(default)]
    pub dominant_second_flag_byte_hex: Option<String>,
    pub dominant_second_flag_byte_count: usize,
    #[serde(default)]
    pub dominant_flag_pair: Option<SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPair>,
    #[serde(default)]
    pub sample_rows: Vec<SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSample>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPair {
    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 SmpSavePlacedStructureDynamicSideBufferShortProfileFlagPairSample {
    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 first_flag_byte: u8,
    pub first_flag_byte_hex: String,
    pub second_flag_byte: u8,
    pub second_flag_byte_hex: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSavePlacedStructureDynamicSideBufferPayloadEnvelopeSample {
    pub sample_index: usize,
    pub name_tag_relative_offset: usize,
    #[serde(default)]
    pub primary_name: Option<String>,
    #[serde(default)]
    pub secondary_name: Option<String>,
    #[serde(default)]
    pub name_payload_end_relative_offset: Option<usize>,
    #[serde(default)]
    pub policy_tag_relative_offset: Option<usize>,
    #[serde(default)]
    pub profile_tag_relative_offset: Option<usize>,
    #[serde(default)]
    pub next_name_tag_relative_offset: Option<usize>,
    #[serde(default)]
    pub name_to_policy_gap_len: Option<usize>,
    #[serde(default)]
    pub policy_chunk_len: Option<usize>,
    #[serde(default)]
    pub profile_chunk_len_to_next_name_or_end: Option<usize>,
}
