use serde::{Deserialize, Serialize};

use crate::inspect::smp::common::SmpAsciiPreview;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpRt3105SaveNameTableProbe {
    pub profile_family: String,
    pub source_kind: String,
    pub semantic_family: String,
    pub semantic_alignment: Vec<String>,
    pub header_offset: usize,
    pub header_word_0: u32,
    pub header_word_0_hex: String,
    pub header_word_1: u32,
    pub header_word_1_hex: String,
    pub header_word_2: u32,
    pub header_word_2_hex: String,
    pub entry_stride: usize,
    pub entry_stride_hex: String,
    pub header_prefix_word_count: usize,
    pub observed_entry_capacity: usize,
    pub observed_entry_count: usize,
    pub zero_trailer_entry_count: usize,
    pub nonzero_trailer_entry_count: usize,
    pub distinct_trailer_words: Vec<u32>,
    pub distinct_trailer_hex_words: Vec<String>,
    pub zero_trailer_entry_names: Vec<String>,
    pub entries_offset: usize,
    pub entries_end_offset: usize,
    pub trailing_footer_hex: String,
    pub footer_progress_word_0: u32,
    pub footer_progress_word_0_hex: String,
    pub footer_progress_word_1: u32,
    pub footer_progress_word_1_hex: String,
    pub footer_trailing_byte: u8,
    pub footer_trailing_byte_hex: String,
    pub footer_grounded_alignments: Vec<String>,
    pub entries: Vec<SmpRt3105SaveNameTableEntry>,
    pub evidence: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpRt3105SaveNamedLocomotiveAvailabilityProbe {
    pub profile_family: String,
    pub source_kind: String,
    pub semantic_family: String,
    pub semantic_alignment: Vec<String>,
    pub entries_offset: usize,
    pub entry_stride: usize,
    pub entry_stride_hex: String,
    pub observed_entry_count: usize,
    pub zero_availability_count: usize,
    pub zero_availability_names: Vec<String>,
    pub entries_end_offset: usize,
    pub entries: Vec<SmpRt3105SaveNameTableEntry>,
    pub evidence: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpRt3105SaveNameTableEntry {
    pub index: usize,
    pub offset: usize,
    pub text: String,
    pub availability_dword: u32,
    pub availability_dword_hex: String,
    pub trailer_word: u32,
    pub trailer_word_hex: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpClassicRehydrateProfileProbe {
    pub profile_family: String,
    pub progress_32dc_offset: usize,
    pub progress_3714_offset: usize,
    pub progress_3715_offset: usize,
    pub packed_profile_offset: usize,
    pub packed_profile_len: usize,
    pub packed_profile_len_hex: String,
    pub packed_profile_block: SmpClassicPackedProfileBlock,
    pub ascii_runs: Vec<SmpAsciiPreview>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpClassicPackedProfileBlock {
    pub relative_len: usize,
    pub relative_len_hex: String,
    pub leading_word_0: u32,
    pub leading_word_0_hex: String,
    pub trailing_zero_word_count_after_leading_word: usize,
    pub map_path_offset: usize,
    pub map_path: Option<String>,
    pub display_name_offset: usize,
    pub display_name: Option<String>,
    pub profile_byte_0x77: u8,
    pub profile_byte_0x77_hex: String,
    pub profile_byte_0x82: u8,
    pub profile_byte_0x82_hex: String,
    pub profile_byte_0x97: u8,
    pub profile_byte_0x97_hex: String,
    pub profile_byte_0xc5: u8,
    pub profile_byte_0xc5_hex: String,
    pub stable_nonzero_words: Vec<SmpPackedProfileWordLane>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpRt3105PackedProfileProbe {
    pub profile_family: String,
    pub packed_profile_offset: usize,
    pub packed_profile_len: usize,
    pub packed_profile_len_hex: String,
    pub packed_profile_block: SmpRt3105PackedProfileBlock,
    pub ascii_runs: Vec<SmpAsciiPreview>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpRt3105PackedProfileBlock {
    pub relative_len: usize,
    pub relative_len_hex: String,
    pub leading_word_0: u32,
    pub leading_word_0_hex: String,
    pub trailing_zero_word_count_after_leading_word: usize,
    pub header_flag_word_3: u32,
    pub header_flag_word_3_hex: String,
    pub map_path_offset: usize,
    pub map_path: Option<String>,
    pub display_name_offset: usize,
    pub display_name: Option<String>,
    pub profile_byte_0x77: u8,
    pub profile_byte_0x77_hex: String,
    pub profile_byte_0x82: u8,
    pub profile_byte_0x82_hex: String,
    pub profile_byte_0x97: u8,
    pub profile_byte_0x97_hex: String,
    pub profile_byte_0xc5: u8,
    pub profile_byte_0xc5_hex: String,
    pub stable_nonzero_words: Vec<SmpPackedProfileWordLane>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpPackedProfileWordLane {
    pub relative_offset: usize,
    pub relative_offset_hex: String,
    pub value: u32,
    pub value_hex: String,
}
