
# build.ps1 - 智能 WASM 构建脚本
param(
    [switch]$Clean,
    [switch]$Serve,
    [switch]$Test,
    [string]$BuildType = "Release"
)

Write-Host "=========================================" -ForegroundColor Cyan
Write-Host "   智能 JSON-WASM 项目构建系统         " -ForegroundColor Cyan
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host ""

# 1. 设置环境变量
$emsdkCandidates = @()

if ($env:EMSDK) {
    $emsdkCandidates += $env:EMSDK
}

$emsdkCandidates += "E:\emsdk"
$emsdkCandidates += (Join-Path (Split-Path $PSScriptRoot -Parent) "..\emsdk")
$emsdkCandidates += (Join-Path (Split-Path $PSScriptRoot -Parent) "emsdk")

$emccCommand = Get-Command emcc -ErrorAction SilentlyContinue
if ($emccCommand -and $emccCommand.Source) {
    $emccSourceDir = Split-Path $emccCommand.Source -Parent
    if (Test-Path (Join-Path $emccSourceDir "emcc.ps1")) {
        $emsdkCandidates += (Split-Path (Split-Path $emccSourceDir -Parent) -Parent)
    }
}

$EmsdkPath = $null
foreach ($candidate in $emsdkCandidates | Select-Object -Unique) {
    if (-not [string]::IsNullOrWhiteSpace($candidate)) {
        try {
            if (Test-Path $candidate) {
                $resolvedCandidate = [System.IO.Path]::GetFullPath($candidate)
                if (Test-Path (Join-Path $resolvedCandidate "upstream\emscripten\emcc.ps1")) {
                    $EmsdkPath = $resolvedCandidate
                    break
                }
            }
        } catch {
            continue
        }
    }
}

if (-not $EmsdkPath) {
    Write-Host "[错误] 未找到 Emscripten" -ForegroundColor Red
    Write-Host "请设置 EMSDK 环境变量，或确认 emsdk 已安装。" -ForegroundColor Yellow
    exit 1
}

# 设置 PATH
$env:PATH = "$EmsdkPath\upstream\emscripten;$env:PATH"
Write-Host "[✓] 设置 Emscripten 环境: $EmsdkPath" -ForegroundColor Green

# 2. 清理旧构建
if ($Clean) {
    Write-Host "[ ] 清理构建文件..." -ForegroundColor Cyan
    Remove-Item -Path "build", "public/wasm" -Recurse -Force -ErrorAction SilentlyContinue
    Write-Host "[✓] 清理完成" -ForegroundColor Green
}

# 3. 创建目录
New-Item -Path "build", "public/wasm" -ItemType Directory -Force | Out-Null

# 4. 编译 WASM
Write-Host "[ ] 编译智能 WASM 模块..." -ForegroundColor Cyan
$startTime = Get-Date

# 编译命令 - 使用当前真实业务模块源码
$compileResult = emcc `
    src/api/KinematicsWebAPI.Core.cpp `
    src/api/KinematicsWebAPI.RobotCommands.cpp `
    src/api/KinematicsWebAPI.SpcCommands.cpp `
    src/api/KinematicsWebAPI.FourBarCommands.cpp `
    src/api/KinematicsWebAPI.QuadrupedCommands.cpp `
    src/main.cpp `
    src/Robot.cpp `
    src/spc_core.cpp `
    src/QuadrupedRobotSimulation/RobotConfig.cpp `
    src/QuadrupedRobotSimulation/BaseClass.cpp `
    src/QuadrupedRobotSimulation/KinematicsSimulation.cpp `
    src/QuadrupedRobotSimulation/CompleteJsonExporter.cpp `
    src/QuadrupedRobotSimulation/KinematicsReverse.cpp `
    src/QuadrupedRobotSimulation/KinematicsHelper.cpp `
    src/QuadrupedRobotSimulation/SharedGeometry.cpp `
    src/FourBarMechanism/CrankSliderMechanism.cpp `
    src/FourBarMechanism/CrankRockingBlockMechanism_Forward.cpp `
    src/FourBarMechanism/CrankRockingBlockMechanism_Inverse.cpp `
    src/FourBarMechanism/FourBarMechanism.cpp `
    src/FourBarMechanism/SliderCrankMechanism.cpp `
    src/RobotManager.cpp `
    src/utils.cpp `
    src/math_utils.cpp `
    src/smart_json_wrapper.cpp `
    third_party/kdl_parser/src/kdl_parser.cpp `
    third_party/kdl_parser/src/joint.cpp `
    third_party/kdl_parser/src/link.cpp `
    third_party/kdl_parser/src/model.cpp `
    third_party/kdl_parser/src/pose.cpp `
    third_party/kdl_parser/src/tinystr.cpp `
    third_party/kdl_parser/src/tinyxml.cpp `
    third_party/kdl_parser/src/tinyxml2.cpp `
    third_party/kdl_parser/src/tinyxmlerror.cpp `
    third_party/kdl_parser/src/tinyxmlparser.cpp `
    third_party/kdl_parser/src/twist.cpp `
    third_party/kdl_parser/src/world.cpp `
    -I./include `
    -I./third_party `
    -I./third_party/kdl_parser/include `
    -I./third_party/orocos_kdl/install_wasm/include `
    -I./third_party/eigen3 `
    -L./third_party/orocos_kdl/install_wasm/lib `
    -lorocos-kdl `
    -std=c++17 `
    -s WASM=1 `
    -s EXPORTED_FUNCTIONS='["_init_func","_func","_smart_process_json","_smart_get_function_list","_smart_get_function_info","_smart_test_match","_smart_get_version","_smart_free_string","_malloc","_free","_add","_subtract","_multiply","_divide","_fibonacci","_create_buffer","_destroy_buffer","_compute_sum","_get_greeting","_main"]' `
    -s EXPORTED_RUNTIME_METHODS='["UTF8ToString","stringToUTF8","lengthBytesUTF8","ccall","cwrap","HEAPU8","HEAP8","HEAPF32","HEAPF64"]' `
    -s MODULARIZE=1 `
    -s EXPORT_NAME='createSmartMathModule' `
    -s ALLOW_MEMORY_GROWTH=1 `
    -s ENVIRONMENT='web,node,worker' `
    -s ASSERTIONS=1 `
    -s DISABLE_EXCEPTION_CATCHING=0 `
    -s INITIAL_MEMORY=67108864 `
    -s MAXIMUM_MEMORY=268435456 `
    -s STACK_SIZE=5242880 `
    -s USE_PTHREADS=0 `
    -O3 `
    -Wno-deprecated-literal-operator `
    -o public/wasm/smart_math.js 2>&1

$endTime = Get-Date
$duration = ($endTime - $startTime).TotalSeconds

if ($LASTEXITCODE -ne 0) {
    Write-Host "[✗] 编译失败" -ForegroundColor Red
    Write-Host $compileResult -ForegroundColor Red
    exit 1
}

Write-Host "[✓] 编译完成" -ForegroundColor Green

# 5. 检查生成的文件
$jsFile = Get-Item "public/wasm/smart_math.js" -ErrorAction SilentlyContinue
$wasmFile = Get-Item "public/wasm/smart_math.wasm" -ErrorAction SilentlyContinue

if (-not $jsFile -or -not $wasmFile) {
    Write-Host "[✗] 未找到生成文件" -ForegroundColor Red
    exit 1
}

$jsSize = $jsFile.Length / 1KB
$wasmSize = $wasmFile.Length / 1KB

# 6. 显示构建结果
Write-Host ""
Write-Host "构建成功" -ForegroundColor Green
Write-Host ("=" * 50) -ForegroundColor DarkGray
Write-Host "生成文件:" -ForegroundColor White
Write-Host " - smart_math.js   ($($jsSize.ToString('F1')) KB)" -ForegroundColor Gray
Write-Host " - smart_math.wasm ($($wasmSize.ToString('F1')) KB)" -ForegroundColor Gray
Write-Host ""
Write-Host "功能特性:" -ForegroundColor White
Write-Host " - 机器人正逆解业务接口 (func/init_func)" -ForegroundColor Gray
Write-Host " - SPC / 四足机器人 / 连杆机构业务接口" -ForegroundColor Gray
Write-Host " - 智能 JSON 数学测试接口" -ForegroundColor Gray
Write-Host " - Node / Web 双环境加载" -ForegroundColor Gray
Write-Host " - 与 Emscripten 内存管理兼容" -ForegroundColor Gray
Write-Host " - 批量回归测试可直接调用" -ForegroundColor Gray
Write-Host ""
Write-Host "输出目录: $((Get-Location).Path)\public\wasm" -ForegroundColor Gray
Write-Host "编译耗时: $($duration.ToString('F2')) 秒" -ForegroundColor Gray
Write-Host ""

# 7. 生成 JavaScript 包装器（可选）
Write-Host "[ ] 生成 JavaScript 包装器..." -ForegroundColor Cyan

$jsWrapper = @'
// Smart WASM JSON API JavaScript 包装器
class SmartWasmAPI {
    constructor() {
        this.module = null;
        this.initialized = false;
    }

    allocString(value) {
        const size = this.module.lengthBytesUTF8(value) + 1;
        const ptr = this.module._malloc(size);
        this.module.stringToUTF8(value, ptr, size);
        return ptr;
    }

    async initialize() {
        if (this.initialized) return;

        // 加载 WASM 模块
        this.module = await createSmartMathModule();
        this.initialized = true;
        
        console.log('Smart WASM API 初始化完成');
        return this;
    }

    async initializeBusinessApi() {
        if (!this.initialized) {
            await this.initialize();
        }

        let responsePtr = null;

        try {
            responsePtr = this.module._init_func();
            const responseStr = this.module.UTF8ToString(responsePtr);
            return JSON.parse(responseStr);
        } finally {
            if (responsePtr) {
                this.module._smart_free_string(responsePtr);
            }
        }
    }

    async processBusinessRequest(jsonRequest) {
        if (!this.initialized) {
            await this.initialize();
        }

        let requestPtr = null;
        let responsePtr = null;

        try {
            requestPtr = this.allocString(JSON.stringify(jsonRequest));
            responsePtr = this.module._func(requestPtr);
            const responseStr = this.module.UTF8ToString(responsePtr);
            return JSON.parse(responseStr);
        } catch (error) {
            console.error('处理业务 JSON 请求时出错:', error);
            throw error;
        } finally {
            if (requestPtr) {
                this.module._free(requestPtr);
            }
            if (responsePtr) {
                this.module._smart_free_string(responsePtr);
            }
        }
    }

    // 处理 JSON 请求
    async processJsonRequest(jsonRequest) {
        if (!this.initialized) {
            await this.initialize();
        }

        let requestPtr = null;
        let responsePtr = null;

        try {
            // 将 JSON 字符串转换为 WASM 内存中的字符串
            requestPtr = this.allocString(JSON.stringify(jsonRequest));
            
            // 调用 WASM 函数
            responsePtr = this.module._smart_process_json(requestPtr);
            
            // 将结果转换回 JavaScript 字符串
            const responseStr = this.module.UTF8ToString(responsePtr);
            
            // 解析 JSON 结果
            return JSON.parse(responseStr);
        } catch (error) {
            console.error('处理 JSON 请求时出错:', error);
            throw error;
        } finally {
            // 释放内存
            if (requestPtr) {
                this.module._free(requestPtr);
            }
            if (responsePtr) {
                this.module._smart_free_string(responsePtr);
            }
        }
    }

    // 获取函数列表
    async getFunctionList() {
        if (!this.initialized) {
            await this.initialize();
        }

        let responsePtr = null;

        try {
            responsePtr = this.module._smart_get_function_list();
            const responseStr = this.module.UTF8ToString(responsePtr);
            return JSON.parse(responseStr);
        } catch (error) {
            console.error('获取函数列表时出错:', error);
            throw error;
        } finally {
            if (responsePtr) {
                this.module._smart_free_string(responsePtr);
            }
        }
    }

    // 调用特定函数
    async callFunction(funcName, params = {}) {
        const request = {
            req_cmd: funcName,
            ...params
        };
        
        return await this.processJsonRequest(request);
    }

    // 测试智能匹配
    async testSmartMatch(jsonRequest) {
        if (!this.initialized) {
            await this.initialize();
        }

        let requestPtr = null;
        let responsePtr = null;

        try {
            requestPtr = this.allocString(JSON.stringify(jsonRequest));
            responsePtr = this.module._smart_test_match(requestPtr);
            const responseStr = this.module.UTF8ToString(responsePtr);
            return JSON.parse(responseStr);
        } catch (error) {
            console.error('测试智能匹配时出错:', error);
            throw error;
        } finally {
            if (requestPtr) {
                this.module._free(requestPtr);
            }
            if (responsePtr) {
                this.module._smart_free_string(responsePtr);
            }
        }
    }

    // 获取版本信息
    async getVersion() {
        if (!this.initialized) {
            await this.initialize();
        }

        let responsePtr = null;

        try {
            responsePtr = this.module._smart_get_version();
            const responseStr = this.module.UTF8ToString(responsePtr);
            return JSON.parse(responseStr);
        } catch (error) {
            console.error('获取版本信息时出错:', error);
            throw error;
        } finally {
            if (responsePtr) {
                this.module._smart_free_string(responsePtr);
            }
        }
    }

    // 直接调用数学函数（绕过 JSON 处理）
    callMathFunction(name, ...args) {
        if (!this.initialized) {
            throw new Error('WASM 模块未初始化');
        }

        switch (name.toLowerCase()) {
            case 'add':
                return this.module._add(args[0] || 0, args[1] || 0);
            case 'subtract':
                return this.module._subtract(args[0] || 0, args[1] || 0);
            case 'multiply':
                return this.module._multiply(args[0] || 0, args[1] || 0);
            case 'divide':
                return this.module._divide(args[0] || 0, args[1] || 1);
            case 'fibonacci':
                return this.module._fibonacci(args[0] || 0);
            default:
                throw new Error('未知的数学函数: ' + name);
        }
    }
}

// 创建全局实例
if (typeof window !== 'undefined') {
    window.SmartWasmAPI = SmartWasmAPI;
}

export default SmartWasmAPI;
'@

$jsWrapper | Out-File -FilePath "public/wasm/smart_api_wrapper.js" -Encoding UTF8
Write-Host "[✓] 生成 JavaScript 包装器" -ForegroundColor Green

# 8. 本地测试（可选）
if ($Test) {
    Write-Host "[ ] 运行本地测试..." -ForegroundColor Cyan

    try {
        node --version 2>&1 | Out-Null
        if ($LASTEXITCODE -eq 0) {
            Write-Host "[ ] 执行 WASM 回归测试..." -ForegroundColor Cyan
            node scripts/run_wasm_tests.js
        }
    } catch {
        Write-Host "[!] 本地测试跳过（需要 Node.js）" -ForegroundColor Yellow
    }
}

# 9. 启动开发服务器（可选）
if ($Serve) {
    Write-Host "[ ] 启动开发服务器..." -ForegroundColor Cyan
    Write-Host "    访问: http://localhost:8080/smart_test.html" -ForegroundColor Yellow
    Write-Host "    按 Ctrl+C 停止服务器" -ForegroundColor Yellow
    Write-Host ""
    
    Set-Location "public"
    python -m http.server 8080
}

Write-Host ""
Write-Host "使用提示:" -ForegroundColor White
Write-Host " - 在 VS Code 中按 F5 启动调试" -ForegroundColor Gray
Write-Host " - 使用 Ctrl+Shift+B 快速构建" -ForegroundColor Gray
Write-Host " - 查看 public/wasm/smart_api_wrapper.js 了解 JavaScript API 使用" -ForegroundColor Gray
Write-Host " - 运行 npm run serve 启动开发服务器" -ForegroundColor Gray
Write-Host ""

