//! 构建脚本: 查找并链接 Darra.Core 动态库, 生成版本信息

use std::env;
use std::path::{Path, PathBuf};

fn main() {
    // === 查找动态库搜索路径 ===
    let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();

    let search_paths = collect_search_paths(&target_os);
    for path in &search_paths {
        println!("cargo:rustc-link-search=native={}", path.display());
    }

    // === 链接动态库 ===
    match target_os.as_str() {
        "windows" => {
            println!("cargo:rustc-link-lib=dylib=Darra.Core");
        }
        "linux" => {
            println!("cargo:rustc-link-lib=dylib=DarraCore");
        }
        _ => {
            println!("cargo:warning=不支持的目标平台: {}", target_os);
        }
    }

    // === 链接 VMProtect SDK (可选) ===
    link_vmprotect_sdk(&target_os);

    // === 生成版本信息 ===
    generate_version_info();

    // === 重新构建条件 ===
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-env-changed=CORE_LIB_DIR");
    println!("cargo:rerun-if-env-changed=VMPROTECT_SDK_DIR");
}

/// 收集动态库搜索路径
fn collect_search_paths(target_os: &str) -> Vec<PathBuf> {
    let mut paths = Vec::new();

    // 优先使用环境变量指定的路径
    if let Ok(lib_dir) = env::var("CORE_LIB_DIR") {
        let p = PathBuf::from(&lib_dir);
        if p.is_dir() {
            paths.push(p);
        }
    }

    // 项目内置路径 (相对于 Cargo.toml 所在目录)
    let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());

    // 驱动构建输出目录
    let drive_base = manifest_dir
        .parent() // Rust/
        .and_then(|p| p.parent()) // Darra_EtherCAT_ClassLibrary/
        .and_then(|p| p.parent()) // 项目根目录
        .map(|p| p.join("Darra_EtherCAT_Drive"));

    if let Some(ref drive) = drive_base {
        match target_os {
            "windows" => {
                // [2026-05-04] 加 main/win64/ 直接路径 (Core.lib 通常生成在这里)
                let direct_win64 = drive.join("main").join("win64");
                if direct_win64.is_dir() {
                    paths.push(direct_win64);
                }
                // Windows: 优先 Release, 然后 Debug
                for build_type in &["Release", "Debug"] {
                    let p = drive.join("main").join("win64").join("build").join(build_type);
                    if p.is_dir() {
                        paths.push(p);
                    }
                }
                // 测试用 DLL 路径
                let test_dir = drive.join("main").join("test");
                if test_dir.is_dir() {
                    paths.push(test_dir);
                }
            }
            "linux" => {
                let p = drive.join("main").join("linux").join("build");
                if p.is_dir() {
                    paths.push(p);
                }
                // 标准系统路径
                for sys_path in &["/usr/local/lib", "/usr/lib"] {
                    let p = PathBuf::from(sys_path);
                    if p.is_dir() {
                        paths.push(p);
                    }
                }
            }
            _ => {}
        }
    }

    paths
}

/// 从 build_number.txt / minor_version.txt 生成版本信息
fn generate_version_info() {
    let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
    let win64_dir = manifest_dir
        .parent()
        .and_then(|p| p.parent())
        .and_then(|p| p.parent())
        .map(|p| p.join("Darra_EtherCAT_Drive").join("main").join("win64"));

    let build_number = win64_dir
        .as_ref()
        .map(|d| read_version_file(&d.join("build_number.txt")))
        .unwrap_or_else(|| "0".to_string());

    let minor_version = win64_dir
        .as_ref()
        .map(|d| read_version_file(&d.join("minor_version.txt")))
        .unwrap_or_else(|| "0".to_string());

    // 传递给编译器的环境变量
    println!("cargo:rustc-env=BUILD_NUMBER={}", build_number);
    println!("cargo:rustc-env=MINOR_VERSION={}", minor_version);

    if let Some(ref d) = win64_dir {
        println!("cargo:rerun-if-changed={}", d.join("build_number.txt").display());
        println!("cargo:rerun-if-changed={}", d.join("minor_version.txt").display());
    }
}

/// 链接 VMProtect SDK 静态库 (可选)
///
/// VMProtect SDK 提供标记函数 (VMProtectBegin/End 等),
/// 编译时链接 SDK 的 .lib 文件, 运行时通过 protection.rs 动态加载 DLL。
///
/// 搜索路径优先级:
/// 1. VMPROTECT_SDK_DIR 环境变量
/// 2. VMProtect 默认安装目录
fn link_vmprotect_sdk(target_os: &str) {
    // 尝试获取 SDK 目录
    let sdk_dir = env::var("VMPROTECT_SDK_DIR").ok().map(PathBuf::from);

    let search_paths: Vec<PathBuf> = match target_os {
        "windows" => {
            let mut paths = Vec::new();
            if let Some(ref dir) = sdk_dir {
                paths.push(dir.clone());
            }
            // VMProtect 默认安装路径
            paths.push(PathBuf::from(r"C:\Program Files\VMProtect Ultimate\SDK\Lib\Windows"));
            paths
        }
        "linux" => {
            let mut paths = Vec::new();
            if let Some(ref dir) = sdk_dir {
                paths.push(dir.clone());
            }
            paths.push(PathBuf::from("/usr/local/lib"));
            paths
        }
        _ => Vec::new(),
    };

    // 查找 SDK 库文件
    let lib_name = match target_os {
        "windows" => "VMProtectSDK64",
        _ => "VMProtectSDK",
    };

    for path in &search_paths {
        if path.is_dir() {
            let lib_file = match target_os {
                "windows" => path.join(format!("{}.lib", lib_name)),
                _ => path.join(format!("lib{}.a", lib_name)),
            };

            if lib_file.exists() {
                println!("cargo:rustc-link-search=native={}", path.display());
                println!("cargo:rustc-link-lib=static={}", lib_name);
                println!("cargo:warning=已链接 VMProtect SDK: {}", lib_file.display());
                return;
            }
        }
    }

    // SDK 未找到 - 非致命, protection.rs 会在运行时动态加载
    println!("cargo:warning=VMProtect SDK 未找到 (可选), 将使用运行时动态加载");
}

/// 读取版本文件内容, 去除空白字符
fn read_version_file(path: &Path) -> String {
    std::fs::read_to_string(path)
        .unwrap_or_else(|_| "0".to_string())
        .trim()
        .to_string()
}
