//! DLL 版本信息工具
//!
//! 对应 C# Utils/VersionInfo.cs
//! 提供 DLL 版本缓存和校验码计算。
//! 注: 与 statics/version_info.rs 不同，此模块对应 Utils 目录的版本工具。

use crate::utils::ffi;
use std::sync::OnceLock;

/// DLL 版本信息结构体
///
/// 对应 C# DllVersionInfo (Utils 版)
#[derive(Clone, Debug, Default)]
pub struct DllVersionInfoCached {
    pub major: u16,
    pub minor: u16,
    pub patch: u16,
    pub build: u16,
    pub build_date: String,
}

static CACHED_VERSION: OnceLock<DllVersionInfoCached> = OnceLock::new();

/// 获取 DLL 版本信息（缓存）
///
/// 对应 C# DllVersionHelper.Info
pub fn get_dll_version_info() -> &'static DllVersionInfoCached {
    CACHED_VERSION.get_or_init(|| {
        unsafe {
            let ptr = ffi::GetDllVersionInfo();
            if ptr.is_null() {
                return DllVersionInfoCached::default();
            }

            // 读取 version_info_t 结构
            #[repr(C, packed)]
            struct RawVersionInfo {
                major: u16,
                minor: u16,
                patch: u16,
                build: u16,
                build_date: [u8; 32],
            }

            let raw = &*(ptr as *const RawVersionInfo);
            let date_len = raw.build_date.iter().position(|&b| b == 0).unwrap_or(32);
            let build_date = std::str::from_utf8(&raw.build_date[..date_len])
                .unwrap_or("Unknown")
                .to_string();

            DllVersionInfoCached {
                major: raw.major,
                minor: raw.minor,
                patch: raw.patch,
                build: raw.build,
                build_date,
            }
        }
    })
}

/// 获取版本号字符串（格式: "1.0.0.0"）
///
/// 对应 C# DllVersionHelper.VersionNumber
pub fn version_number() -> String {
    let info = get_dll_version_info();
    format!("{}.{}.{}.{}", info.major, info.minor, info.patch, info.build)
}

/// 获取编译日期
///
/// 对应 C# DllVersionHelper.BuildDate
pub fn build_date() -> &'static str {
    &get_dll_version_info().build_date
}
