use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSpecialConditionEntry {
    pub slot_index: u8,
    pub hidden: bool,
    pub label_id: u32,
    pub help_id: u32,
    pub label: String,
    pub value: u32,
    pub value_hex: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpSpecialConditionsProbe {
    pub profile_family: String,
    pub source_kind: String,
    pub table_offset: usize,
    pub table_len: usize,
    pub enabled_visible_count: usize,
    pub enabled_visible_labels: Vec<String>,
    pub hidden_sentinel_slot_index: u8,
    pub hidden_sentinel_value: u32,
    pub hidden_sentinel_value_hex: String,
    pub entries: Vec<SmpSpecialConditionEntry>,
    pub evidence: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLoadedSpecialConditionsTable {
    pub source_kind: String,
    pub table_offset: usize,
    pub table_len: usize,
    pub enabled_visible_count: usize,
    pub enabled_visible_labels: Vec<String>,
    pub entries: Vec<SmpSpecialConditionEntry>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpAlignedRuntimeRuleBandLane {
    pub band_index: usize,
    pub absolute_offset: usize,
    pub relative_offset: usize,
    pub absolute_offset_hex: String,
    pub relative_offset_hex: String,
    pub lane_kind: String,
    pub known_label: Option<String>,
    pub value: u32,
    pub value_hex: String,
    pub probable_f32_le: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpAlignedRuntimeRuleBandProbe {
    pub profile_family: String,
    pub source_kind: String,
    pub band_offset: usize,
    pub band_end_offset: usize,
    pub band_len: usize,
    pub band_len_hex: String,
    pub dword_count: usize,
    pub known_editor_rule_dword_count: usize,
    pub trailing_scalar_index: usize,
    pub trailing_scalar_offset: usize,
    pub trailing_scalar_offset_hex: String,
    pub post_window_overlap_start_index: usize,
    pub post_window_overlap_dword_count: usize,
    pub post_window_overlap_end_index: usize,
    pub post_window_overlap_post_relative_offset_start_hex: String,
    pub post_window_overlap_post_relative_offset_end_hex: String,
    pub nonzero_post_window_overlap_band_indices: Vec<usize>,
    pub nonzero_post_window_overlap_post_relative_offset_hexes: Vec<String>,
    pub nonzero_lane_count: usize,
    pub nonzero_band_indices: Vec<usize>,
    pub nonzero_relative_offset_hexes: Vec<String>,
    pub nonzero_lanes: Vec<SmpAlignedRuntimeRuleBandLane>,
    pub evidence: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpPostSpecialConditionsScalarLane {
    pub absolute_offset: usize,
    pub relative_offset: usize,
    pub absolute_offset_hex: String,
    pub relative_offset_hex: String,
    pub value: u32,
    pub value_hex: String,
    pub probable_f32_le: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpPostTextGroundedFieldObservation {
    pub field_name: String,
    pub runtime_object_offset: usize,
    pub runtime_object_offset_hex: String,
    pub file_offset: usize,
    pub file_offset_hex: String,
    pub field_width_bytes: usize,
    pub field_width_bytes_hex: String,
    pub raw_hex: String,
    pub value_u8: Option<u8>,
    pub value_u8_hex: Option<String>,
    pub value_u32: Option<u32>,
    pub value_u32_hex: Option<String>,
    pub probable_f32_le: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpPostTextFloatAlignmentCandidate {
    pub grounded_field_name: String,
    pub grounded_field_runtime_object_offset: usize,
    pub grounded_field_runtime_object_offset_hex: String,
    pub grounded_field_file_offset: usize,
    pub grounded_field_file_offset_hex: String,
    pub candidate_offset: usize,
    pub candidate_offset_hex: String,
    pub candidate_value: u32,
    pub candidate_value_hex: String,
    pub probable_f32_le: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpPostTextFieldNeighborhoodProbe {
    pub profile_family: String,
    pub source_kind: String,
    pub window_offset: usize,
    pub window_end_offset: usize,
    pub window_len: usize,
    pub window_len_hex: String,
    pub grounded_field_observations: Vec<SmpPostTextGroundedFieldObservation>,
    pub one_byte_early_float_candidates: Vec<SmpPostTextFloatAlignmentCandidate>,
    pub evidence: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLocomotivePolicyFieldObservation {
    pub field_name: String,
    pub runtime_object_offset: usize,
    pub runtime_object_offset_hex: String,
    pub file_offset: usize,
    pub file_offset_hex: String,
    pub field_width_bytes: usize,
    pub field_width_bytes_hex: String,
    pub raw_hex: String,
    pub value_u8: Option<u8>,
    pub value_u8_hex: Option<String>,
    pub value_u32: Option<u32>,
    pub value_u32_hex: Option<String>,
    pub probable_f32_le: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLocomotivePolicyFloatAlignmentCandidate {
    pub grounded_field_name: String,
    pub grounded_field_runtime_object_offset: usize,
    pub grounded_field_runtime_object_offset_hex: String,
    pub grounded_field_file_offset: usize,
    pub grounded_field_file_offset_hex: String,
    pub candidate_offset: usize,
    pub candidate_offset_hex: String,
    pub candidate_value: u32,
    pub candidate_value_hex: String,
    pub probable_f32_le: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpLocomotivePolicyNeighborhoodProbe {
    pub profile_family: String,
    pub source_kind: String,
    pub window_offset: usize,
    pub window_end_offset: usize,
    pub window_len: usize,
    pub window_len_hex: String,
    pub grounded_field_observations: Vec<SmpLocomotivePolicyFieldObservation>,
    pub three_byte_early_float_candidates: Vec<SmpLocomotivePolicyFloatAlignmentCandidate>,
    pub evidence: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpPreRecipeScalarPlateauLane {
    pub absolute_offset: usize,
    pub relative_offset: usize,
    pub absolute_offset_hex: String,
    pub relative_offset_hex: String,
    pub value: u32,
    pub value_hex: String,
    pub probable_f32_le: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpPreRecipeScalarPlateauProbe {
    pub profile_family: String,
    pub source_kind: String,
    pub window_offset: usize,
    pub window_end_offset: usize,
    pub window_len: usize,
    pub window_len_hex: String,
    pub aligned_dword_count: usize,
    pub family_signature: String,
    pub nonzero_lanes: Vec<SmpPreRecipeScalarPlateauLane>,
    pub evidence: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpRecipeBookSummaryBook {
    pub book_index: usize,
    pub book_offset: usize,
    pub book_offset_hex: String,
    pub head_kind: String,
    pub head_nonzero_byte_count: usize,
    pub head_cdcd_byte_count: usize,
    pub head_first_16_hex: String,
    pub max_annual_production_offset: usize,
    pub max_annual_production_offset_hex: String,
    pub max_annual_production_word: u32,
    pub max_annual_production_word_hex: String,
    pub max_annual_production_probable_f32_le: Option<String>,
    pub line_area_offset: usize,
    pub line_area_offset_hex: String,
    pub line_area_len: usize,
    pub line_area_len_hex: String,
    pub line_area_kind: String,
    pub line_area_nonzero_byte_count: usize,
    pub line_area_cdcd_byte_count: usize,
    pub line_area_first_16_hex: String,
    pub lines: Vec<SmpRecipeBookLineSummary>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpRecipeBookLineSummary {
    pub line_index: usize,
    pub line_offset: usize,
    pub line_offset_hex: String,
    pub line_kind: String,
    pub line_signature_kind: String,
    pub imports_to_runtime_descriptor: bool,
    pub runtime_import_branch_kind: String,
    pub line_nonzero_byte_count: usize,
    pub line_cdcd_byte_count: usize,
    pub line_first_16_hex: String,
    pub mode_word_offset: usize,
    pub mode_word_offset_hex: String,
    pub mode_word: u32,
    pub mode_word_hex: String,
    pub annual_amount_offset: usize,
    pub annual_amount_offset_hex: String,
    pub annual_amount_word: u32,
    pub annual_amount_word_hex: String,
    pub annual_amount_probable_f32_le: Option<String>,
    pub supplied_cargo_token_offset: usize,
    pub supplied_cargo_token_offset_hex: String,
    pub supplied_cargo_token_word: u32,
    pub supplied_cargo_token_word_hex: String,
    pub supplied_cargo_token_layout_kind: String,
    pub supplied_cargo_token_window_hex: String,
    pub supplied_cargo_token_window_ascii: String,
    pub supplied_cargo_token_active_in_runtime_import: bool,
    pub supplied_cargo_token_probable_high16_ascii_stem: Option<String>,
    pub demanded_cargo_token_offset: usize,
    pub demanded_cargo_token_offset_hex: String,
    pub demanded_cargo_token_word: u32,
    pub demanded_cargo_token_word_hex: String,
    pub demanded_cargo_token_layout_kind: String,
    pub demanded_cargo_token_window_hex: String,
    pub demanded_cargo_token_window_ascii: String,
    pub demanded_cargo_token_active_in_runtime_import: bool,
    pub demanded_cargo_token_probable_high16_ascii_stem: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpRecipeBookSummaryProbe {
    pub profile_family: String,
    pub source_kind: String,
    pub root_offset: usize,
    pub root_offset_hex: String,
    pub runtime_object_root_offset: usize,
    pub runtime_object_root_offset_hex: String,
    pub book_count: usize,
    pub book_stride: usize,
    pub book_stride_hex: String,
    pub max_annual_production_relative_offset: usize,
    pub max_annual_production_relative_offset_hex: String,
    pub line_area_relative_offset: usize,
    pub line_area_relative_offset_hex: String,
    pub line_count: usize,
    pub line_stride: usize,
    pub line_stride_hex: String,
    pub books: Vec<SmpRecipeBookSummaryBook>,
    pub evidence: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SmpPostSpecialConditionsScalarProbe {
    pub profile_family: String,
    pub source_kind: String,
    pub window_offset: usize,
    pub window_end_offset: usize,
    pub window_len: usize,
    pub window_len_hex: String,
    pub dword_count: usize,
    pub overlap_end_offset: usize,
    pub overlap_end_offset_hex: String,
    pub overlap_dword_count: usize,
    pub overlap_nonzero_dword_count: usize,
    pub overlap_nonzero_relative_offset_hexes: Vec<String>,
    pub tail_offset: usize,
    pub tail_offset_hex: String,
    pub tail_len: usize,
    pub tail_len_hex: String,
    pub tail_dword_count: usize,
    pub tail_runtime_object_offset: usize,
    pub tail_runtime_object_offset_hex: String,
    pub tail_runtime_object_end_offset: usize,
    pub tail_runtime_object_end_offset_hex: String,
    pub tail_runtime_object_validated_byte_mirror: bool,
    pub tail_grounded_live_field_offset: usize,
    pub tail_grounded_live_field_offset_hex: String,
    pub tail_grounded_live_field_name: String,
    pub tail_grounded_live_field_copy_len: usize,
    pub tail_grounded_live_field_copy_len_hex: String,
    pub tail_grounded_live_field_copy_end_offset: usize,
    pub tail_grounded_live_field_copy_end_offset_hex: String,
    pub tail_window_cuts_through_grounded_live_field: bool,
    pub tail_grounded_live_field_remaining_file_window_offset: usize,
    pub tail_grounded_live_field_remaining_file_window_offset_hex: String,
    pub tail_grounded_live_field_remaining_file_window_len: usize,
    pub tail_grounded_live_field_remaining_file_window_len_hex: String,
    pub tail_grounded_live_field_remaining_file_window_nonzero_byte_count: usize,
    pub tail_grounded_live_field_remaining_file_window_first_nonzero_offset: Option<usize>,
    pub tail_grounded_live_field_remaining_file_window_first_nonzero_offset_hex: Option<String>,
    pub tail_grounded_live_field_remaining_file_window_last_nonzero_offset: Option<usize>,
    pub tail_grounded_live_field_remaining_file_window_last_nonzero_offset_hex: Option<String>,
    pub tail_next_grounded_dword_field_offset: usize,
    pub tail_next_grounded_dword_field_offset_hex: String,
    pub tail_next_grounded_dword_field_file_offset: usize,
    pub tail_next_grounded_dword_field_file_offset_hex: String,
    pub tail_second_grounded_dword_field_offset: usize,
    pub tail_second_grounded_dword_field_offset_hex: String,
    pub tail_second_grounded_dword_field_file_offset: usize,
    pub tail_second_grounded_dword_field_file_offset_hex: String,
    pub post_text_field_file_alignment_matches_grounded_dword_fields: bool,
    pub tail_nonzero_dword_count: usize,
    pub tail_first_nonzero_offset: Option<usize>,
    pub tail_first_nonzero_offset_hex: Option<String>,
    pub tail_last_nonzero_offset: Option<usize>,
    pub tail_last_nonzero_offset_hex: Option<String>,
    pub tail_nonzero_relative_offset_hexes: Vec<String>,
    pub nonzero_dword_count: usize,
    pub first_nonzero_offset: Option<usize>,
    pub first_nonzero_offset_hex: Option<String>,
    pub last_nonzero_offset: Option<usize>,
    pub last_nonzero_offset_hex: Option<String>,
    pub nonzero_lanes: Vec<SmpPostSpecialConditionsScalarLane>,
    pub evidence: Vec<String>,
}
