use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use std::cmp::Reverse;
use std::collections::{BTreeMap, BTreeSet};
use std::fs;
use std::path::Path;

use crate::event::conditions::{RuntimeCondition, RuntimeConditionComparator};
use crate::event::effects::RuntimeEffect;
use crate::event::metrics::{
    RuntimeChairmanMetric, RuntimeCompanyConditionTestScope, RuntimeCompanyMetric,
    RuntimePlayerConditionTestScope, RuntimeTerritoryMetric, RuntimeTrackMetric,
};
use crate::event::records::RuntimeEventRecordTemplate;
use crate::event::targets::{
    RuntimeCargoClass, RuntimeCargoPriceTarget, RuntimeCargoProductionTarget,
    RuntimeChairmanTarget, RuntimeCompanyTarget, RuntimePlayerTarget, RuntimeTerritoryTarget,
};
use crate::state::{
    RuntimeCompanyControllerKind, RuntimeCompanyMarketState, RuntimeTrackPieceCounts,
};

pub mod bundle;
pub(crate) mod catalog;
mod common;
pub mod events;
pub mod map_title;
pub mod profiles;
pub mod regions;
pub mod save_load;
pub mod services;
pub mod special_conditions;
pub mod structures;
#[cfg(test)]
mod tests;
pub mod world;

use catalog::conditions::{
    GROUNDED_LOCOMOTIVE_PREFIX, KNOWN_CARGO_SLOT_DEFINITIONS, KnownCargoSlotDefinition,
};
#[cfg(test)]
use catalog::conditions::{
    REAL_BOOK_VALUE_PER_SHARE_CONDITION_ID, REAL_CANDIDATE_AVAILABILITY_CONDITION_TEMPLATE_ID,
    REAL_CARGO_PRODUCTION_CONDITION_TEMPLATE_ID, REAL_CARGO_PRODUCTION_TOTAL_CONDITION_ID,
    REAL_CHAIRMAN_CASH_CONDITION_ID, REAL_CHAIRMAN_HOLDINGS_TOTAL_CONDITION_ID,
    REAL_CHAIRMAN_NET_WORTH_CONDITION_ID, REAL_CHAIRMAN_PURCHASING_POWER_CONDITION_ID,
    REAL_CREDIT_RATING_CONDITION_ID, REAL_FACTORY_PRODUCTION_TOTAL_CONDITION_ID,
    REAL_FARM_MINE_PRODUCTION_TOTAL_CONDITION_ID, REAL_INVESTOR_CONFIDENCE_CONDITION_ID,
    REAL_LIMITED_TRACK_BUILDING_AMOUNT_CONDITION_ID, REAL_MANAGEMENT_ATTITUDE_CONDITION_ID,
    REAL_NAMED_LOCOMOTIVE_AVAILABILITY_CONDITION_ID, REAL_NAMED_LOCOMOTIVE_COST_CONDITION_ID,
    REAL_OTHER_CARGO_PRODUCTION_TOTAL_CONDITION_ID, REAL_PLAYER_VARIABLE_3_CONDITION_ID,
    REAL_PRIME_RATE_CONDITION_ID, REAL_TERRITORY_ACCESS_COST_CONDITION_ID,
    REAL_TERRITORY_VARIABLE_4_CONDITION_ID, REAL_WORLD_VARIABLE_1_CONDITION_ID,
    real_ordinary_condition_metadata,
};
#[cfg(test)]
use catalog::descriptors::real_grouped_effect_runtime_status_name;
use catalog::descriptors::{
    REAL_GROUPED_EFFECT_DESCRIPTOR_METADATA, RealGroupedEffectDescriptorMetadata,
    RealGroupedEffectRuntimeStatus, checked_in_event_effect_descriptor_rows,
};
use catalog::fixups::POST_LOAD_SCENARIO_FIXUP_TITLE_SET;
use catalog::offsets::bundle::{
    ASCII_PREVIEW_CHAR_LIMIT, MAP_TITLE_HINT_ASCII_FRAGMENT_MAX_LEN,
    MAP_TITLE_HINT_REFERENCE_PAIR_DISTANCE_LIMIT,
};
#[cfg(test)]
use catalog::offsets::events::{
    EVENT_RUNTIME_COLLECTION_CLOSE_TAG, EVENT_RUNTIME_COLLECTION_METADATA_TAG,
    EVENT_RUNTIME_COLLECTION_PACKED_STATE_VERSION, EVENT_RUNTIME_COLLECTION_RECORDS_TAG,
    PACKED_EVENT_REAL_COMPACT_CONTROL_LEN, PACKED_EVENT_REAL_CONDITION_MARKER,
    PACKED_EVENT_REAL_CONDITION_ROW_LEN, PACKED_EVENT_REAL_GROUP_COUNT,
    PACKED_EVENT_REAL_GROUPED_EFFECT_MARKER, PACKED_EVENT_REAL_GROUPED_EFFECT_ROW_LEN,
    PACKED_EVENT_REAL_RECORD_TERMINATOR_MARKER, PACKED_EVENT_RECORD_SYNTHETIC_MAGIC,
    PACKED_EVENT_RECORD_TEMPLATE_SYNTHETIC_MAGIC, PACKED_EVENT_RECORDS_SYNTHETIC_MAGIC,
};
use catalog::offsets::regions::{
    INDEXED_COLLECTION_SERIALIZED_HEADER_DWORD_COUNT, INDEXED_COLLECTION_SERIALIZED_HEADER_LEN,
    SAVE_REGION_COLLECTION_DIRECTORY_ENTRY_DWORD_COUNT,
    SAVE_REGION_COLLECTION_DIRECTORY_ROOT_DWORD_INDEX, SAVE_REGION_FIXED_ROW_CANDIDATE_PROBE_LIMIT,
    SAVE_REGION_FIXED_ROW_DWORD_LANE_COUNT, SAVE_REGION_FIXED_ROW_STRIDE,
    SAVE_REGION_QUEUED_NOTICE_NODE_KIND, SAVE_REGION_QUEUED_NOTICE_NODE_LEN,
    SAVE_REGION_QUEUED_NOTICE_PAYLOAD_SEED, SAVE_REGION_RECORD_NAME_TAG,
    SAVE_REGION_RECORD_POLICY_TAG, SAVE_REGION_RECORD_PROFILE_TAG,
};
use catalog::offsets::special_conditions::{
    LOCOMOTIVE_POLICY_FIELD_0_RUNTIME_OBJECT_OFFSET,
    LOCOMOTIVE_POLICY_FIELD_1_RUNTIME_OBJECT_OFFSET,
    LOCOMOTIVE_POLICY_FIELD_2_RUNTIME_OBJECT_OFFSET,
    LOCOMOTIVE_POLICY_FIELD_3_RUNTIME_OBJECT_OFFSET,
    LOCOMOTIVE_POLICY_FIELD_4_RUNTIME_OBJECT_OFFSET,
    LOCOMOTIVE_POLICY_FIELD_5_RUNTIME_OBJECT_OFFSET,
    LOCOMOTIVE_POLICY_FIELD_NEG1_RUNTIME_OBJECT_OFFSET,
    LOCOMOTIVE_POLICY_FIELD_NEG2_RUNTIME_OBJECT_OFFSET,
    LOCOMOTIVE_POLICY_FIELD_NEG3_RUNTIME_OBJECT_OFFSET, LOCOMOTIVE_POLICY_NEIGHBORHOOD_END_OFFSET,
    LOCOMOTIVE_POLICY_NEIGHBORHOOD_OFFSET,
    POST_SPECIAL_CONDITIONS_GROUNDED_TEXT_FIELD_FILE_END_OFFSET,
    POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_FILE_OFFSET,
    POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_0_OFFSET,
    POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_FILE_OFFSET,
    POST_SPECIAL_CONDITIONS_NEXT_GROUNDED_DWORD_FIELD_1_OFFSET,
    POST_SPECIAL_CONDITIONS_SCALAR_END_OFFSET, POST_SPECIAL_CONDITIONS_SCALAR_OFFSET,
    POST_SPECIAL_CONDITIONS_SCALAR_OVERLAP_END_OFFSET,
    POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_END_OFFSET,
    POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_COPY_LEN,
    POST_SPECIAL_CONDITIONS_SCALAR_TAIL_GROUNDED_TEXT_FIELD_OFFSET,
    POST_SPECIAL_CONDITIONS_SCALAR_TAIL_OFFSET,
    POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_END_OFFSET,
    POST_SPECIAL_CONDITIONS_SCALAR_TAIL_RUNTIME_OBJECT_OFFSET,
    POST_TEXT_FIELD_0_RUNTIME_OBJECT_OFFSET, POST_TEXT_FIELD_1_RUNTIME_OBJECT_OFFSET,
    POST_TEXT_FIELD_2_RUNTIME_OBJECT_OFFSET, POST_TEXT_FIELD_3_RUNTIME_OBJECT_OFFSET,
    POST_TEXT_FIELD_4_RUNTIME_OBJECT_OFFSET, POST_TEXT_FIELD_5_RUNTIME_OBJECT_OFFSET,
    POST_TEXT_FIELD_NEIGHBORHOOD_END_OFFSET, POST_TEXT_FIELD_NEIGHBORHOOD_OFFSET,
    PRE_RECIPE_SCALAR_PLATEAU_END_OFFSET, PRE_RECIPE_SCALAR_PLATEAU_OFFSET, RECIPE_BOOK_COUNT,
    RECIPE_BOOK_HEAD_SAMPLE_LEN, RECIPE_BOOK_LINE_AREA_LEN, RECIPE_BOOK_LINE_AREA_OFFSET,
    RECIPE_BOOK_LINE_COUNT, RECIPE_BOOK_LINE_STRIDE, RECIPE_BOOK_MAX_ANNUAL_PRODUCTION_OFFSET,
    RECIPE_BOOK_ROOT_OFFSET, RECIPE_BOOK_STRIDE, RECIPE_BOOK_SUMMARY_END_OFFSET,
    SMP_ALIGNED_RUNTIME_RULE_DWORD_COUNT, SMP_ALIGNED_RUNTIME_RULE_END_OFFSET,
    SMP_ALIGNED_RUNTIME_RULE_KNOWN_EDITOR_RULE_COUNT,
    SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_DWORD_COUNT,
    SMP_ALIGNED_RUNTIME_RULE_POST_WINDOW_OVERLAP_START_INDEX, SPECIAL_CONDITION_COUNT,
    SPECIAL_CONDITION_HIDDEN_SENTINEL_SLOT, SPECIAL_CONDITIONS_OFFSET,
};
#[cfg(test)]
use catalog::offsets::world::{
    RT3_SAVE_WORLD_BLOCK_BANKRUPTCY_POLICY_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_BOND_POLICY_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_BUILDING_DENSITY_GROWTH_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_CAMPAIGN_OVERRIDE_FLAG_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_STRIDE, RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_COUNT,
    RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_SELECTOR_RELATIVE_OFFSET, RT3_SAVE_WORLD_BLOCK_CHUNK_TAG,
    RT3_SAVE_WORLD_BLOCK_DIVIDEND_POLICY_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_ECONOMIC_TUNING_MIRROR_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_ECONOMIC_TUNING_PRIMARY_RELATIVE_OFFSETS,
    RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_ROOT_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_WINDOW_LEN_DWORDS,
    RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_MULTIPLIER_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_ISSUE_0X37_VALUE_RELATIVE_OFFSET, RT3_SAVE_WORLD_BLOCK_LEN,
    RT3_SAVE_WORLD_BLOCK_NEXT_CHUNK_TAG,
    RT3_SAVE_WORLD_BLOCK_SELECTED_CHAIRMAN_PROFILE_ID_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_SELECTED_COMPANY_ID_RELATIVE_OFFSET,
    RT3_SAVE_WORLD_BLOCK_STOCK_POLICY_RELATIVE_OFFSET,
};
use catalog::special_conditions::{
    KNOWN_SPECIAL_CONDITION_DEFINITIONS, known_special_condition_definition_for_label_id,
};
use common::*;

pub use catalog::SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION;
