use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct WinHeaderWord {
    pub offset: usize,
    pub offset_hex: String,
    pub value: u32,
    pub value_hex: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct WinResourceReference {
    pub offset: usize,
    pub offset_hex: String,
    pub name: String,
}

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

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct WinResourceRecordSample {
    pub offset: usize,
    pub offset_hex: String,
    pub name: String,
    pub delta_from_previous: Option<usize>,
    pub delta_from_previous_hex: Option<String>,
    pub prelude_words: Vec<WinHeaderWord>,
    pub post_name_word_0: u32,
    pub post_name_word_0_hex: String,
    pub post_name_word_0_high_u16: u16,
    pub post_name_word_0_high_u16_hex: String,
    pub post_name_word_0_low_u16: u16,
    pub post_name_word_0_low_u16_hex: String,
    pub post_name_word_1: u32,
    pub post_name_word_1_hex: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct WinResourceSelectorRecord {
    pub offset: usize,
    pub offset_hex: String,
    pub name: String,
    pub post_name_word_0: u32,
    pub post_name_word_0_hex: String,
    pub selector_high_u16: u16,
    pub selector_high_u16_hex: String,
    pub selector_low_u16: u16,
    pub selector_low_u16_hex: String,
    pub post_name_word_1: u32,
    pub post_name_word_1_hex: String,
    pub post_name_word_1_high_u16: u16,
    pub post_name_word_1_high_u16_hex: String,
    pub post_name_word_1_middle_u16: u16,
    pub post_name_word_1_middle_u16_hex: String,
    pub post_name_word_1_low_u16: u16,
    pub post_name_word_1_low_u16_hex: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct WinAnonymousSelectorRecord {
    pub record_offset: usize,
    pub record_offset_hex: String,
    pub preceding_named_record_name: Option<String>,
    pub preceding_named_record_offset_hex: Option<String>,
    pub following_named_record_name: Option<String>,
    pub following_named_record_offset_hex: Option<String>,
    pub selector_word_0: u32,
    pub selector_word_0_hex: String,
    pub selector_word_0_high_u16: u16,
    pub selector_word_0_high_u16_hex: String,
    pub selector_word_0_low_u16: u16,
    pub selector_word_0_low_u16_hex: String,
    pub selector_word_1: u32,
    pub selector_word_1_hex: String,
    pub selector_word_1_middle_u16: u16,
    pub selector_word_1_middle_u16_hex: String,
    pub body_word_0: u32,
    pub body_word_0_hex: String,
    pub body_word_1: u32,
    pub body_word_1_hex: String,
    pub body_word_2: u32,
    pub body_word_2_hex: String,
    pub body_word_3: u32,
    pub body_word_3_hex: String,
    pub footer_word_0: u32,
    pub footer_word_0_hex: String,
    pub footer_word_1: u32,
    pub footer_word_1_hex: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct WinInspectionReport {
    pub file_size: usize,
    pub common_header_len: usize,
    pub common_header_len_hex: String,
    pub shared_header_words: Vec<WinHeaderWord>,
    pub matches_observed_common_signature: bool,
    pub common_resource_record_prelude_prefix_words: Option<Vec<String>>,
    pub name_len_matches_prelude_word_3_plus_nul_count: usize,
    pub inline_root_resource_name: Option<String>,
    pub inline_root_resource_offset: Option<usize>,
    pub inline_root_resource_offset_hex: Option<String>,
    pub imb_reference_count: usize,
    pub unique_imb_reference_count: usize,
    pub unique_imb_references: Vec<String>,
    pub dominant_reference_deltas: Vec<WinReferenceDeltaFrequency>,
    pub resource_selector_records: Vec<WinResourceSelectorRecord>,
    pub anonymous_selector_records: Vec<WinAnonymousSelectorRecord>,
    pub first_resource_record_samples: Vec<WinResourceRecordSample>,
    pub first_imb_references: Vec<WinResourceReference>,
    pub notes: Vec<String>,
}
