use crate::capture::{
    CargoCollectionProbe, CargoCollectionProbeRow, IndexedCollectionProbe,
    IndexedCollectionProbeRow, sample_finance_snapshot, write_cargo_collection_probe,
    write_finance_snapshot_bundle, write_finance_snapshot_only, write_indexed_collection_probe,
};
use core::ffi::{c_char, c_void};
use core::mem;
use core::ptr;
use std::env;
use std::fmt::Write as _;
use std::path::PathBuf;
use std::sync::OnceLock;
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
use std::thread;
use std::time::Duration;

use rrt_model::finance::{
    AnnualFinancePolicy, BondPosition, CompanyFinanceState, FinanceSnapshot, GrowthSetting,
};

mod auto_load;
mod capture;
mod constants;
mod detours;
mod ffi;
mod install;
mod logging;
mod memory;
mod state;

use auto_load::*;
use capture::*;
use constants::*;
use detours::*;
use ffi::*;
use install::*;
use logging::*;
use memory::*;
use state::*;

#[unsafe(no_mangle)]
pub extern "system" fn DllMain(module: *mut c_void, reason: u32, _reserved: *mut c_void) -> i32 {
    if reason == DLL_PROCESS_ATTACH {
        unsafe {
            let _ = DisableThreadLibraryCalls(module);
            OutputDebugStringA(DEBUG_MESSAGE.as_ptr().cast());
            append_attach_log();
        }
    }
    1
}

#[unsafe(no_mangle)]
pub extern "system" fn DirectInput8Create(
    instance: *mut c_void,
    version: u32,
    riid: *const Guid,
    out: *mut *mut c_void,
    outer: *mut c_void,
) -> i32 {
    maybe_emit_finance_template_bundle();
    maybe_start_finance_capture_thread();
    maybe_start_cargo_capture_thread();
    maybe_install_auto_load_hook();

    let direct_input8_create = unsafe { load_direct_input8_create() };
    match direct_input8_create {
        Some(callback) => unsafe { callback(instance, version, riid, out, outer) },
        None => E_FAIL,
    }
}
