@echo off
REM PCode Windows Dependency Installation Script
REM Automatically installs missing dependencies based on version requirements

setlocal EnableDelayedExpansion

REM Locate shared library for JSON escaping
set "SCRIPT_DIR=%~dp0"
set "LIB_DIR=%SCRIPT_DIR%..\lib"
set "ESCAPE_FUNC=%LIB_DIR%\escape_json_string.bat"

REM Default values
set REGION=global
set ARCH=%PROCESSOR_ARCHITECTURE%
set DRY_RUN=0
set VERBOSE=0
set INSTALLED_COUNT=0
set FAILED_COUNT=0

REM Locate dependencies.env file
REM The env file contains version requirements auto-generated from manifest.json
set "ENV_FILE=%SCRIPT_DIR%dependencies.env"

if not exist "%ENV_FILE%" (
    echo [ERROR] dependencies.env file not found at %ENV_FILE%
    echo This file is auto-generated during build. Please ensure you have a complete package.
    endlocal
    exit /b 1
)

REM Read version requirements from dependencies.env
REM Parse KEY=VALUE format from the env file
for /f "usebackq tokens=1,2 delims==" %%a in ("%ENV_FILE%") do (
    if "%%a"=="DOTNET_MIN_VERSION" set DOTNET_MIN_VERSION=%%b
    if "%%a"=="DOTNET_RECOMMENDED_VERSION" set DOTNET_RECOMMENDED_VERSION=%%b
    if "%%a"=="NODE_MIN_VERSION" set NODE_MIN_VERSION=%%b
    if "%%a"=="NODE_RECOMMENDED_VERSION" set NODE_RECOMMENDED_VERSION=%%b
    if "%%a"=="NPM_MIN_VERSION" set NPM_MIN_VERSION=%%b
    if "%%a"=="NPM_RECOMMENDED_VERSION" set NPM_RECOMMENDED_VERSION=%%b
    if "%%a"=="CLAUDE_CODE_MIN_VERSION" set CLAUDE_CODE_MIN_VERSION=%%b
    if "%%a"=="OPENSPEC_MIN_VERSION" set OPENSPEC_MIN_VERSION=%%b
    if "%%a"=="OPENSPEC_MAX_VERSION" set OPENSPEC_MAX_VERSION=%%b
)

REM Set default values in case env file is missing some variables
if "%DOTNET_MIN_VERSION%"=="" set DOTNET_MIN_VERSION=10.0
if "%DOTNET_RECOMMENDED_VERSION%"=="" set DOTNET_RECOMMENDED_VERSION=10.0
if "%NODE_MIN_VERSION%"=="" set NODE_MIN_VERSION=18.0.0
if "%NODE_RECOMMENDED_VERSION%"=="" set NODE_RECOMMENDED_VERSION=24.12.0
if "%NPM_MIN_VERSION%"=="" set NPM_MIN_VERSION=9.0.0
if "%NPM_RECOMMENDED_VERSION%"=="" set NPM_RECOMMENDED_VERSION=10.9.0
if "%CLAUDE_CODE_MIN_VERSION%"=="" set CLAUDE_CODE_MIN_VERSION=1.0.0
if "%OPENSPEC_MIN_VERSION%"=="" set OPENSPEC_MIN_VERSION=0.23.0
if "%OPENSPEC_MAX_VERSION%"=="" set OPENSPEC_MAX_VERSION=1.0.0

echo === PCode Dependency Installation ===
echo Platform: Windows (%ARCH%)
echo Region: %REGION%
echo.

REM Parse arguments
:parse_args
if "%~1"=="" goto done_parsing
if "%~1"=="--region=cn" set REGION=china
if "%~1"=="--region=global" set REGION=global
echo %~1 | findstr /C:"--region=" >nul && set REGION=%~1
echo %~1 | findstr /C:"--region=" >nul && set REGION=!REGION:--region=!
echo %~1 | findstr /C:"--arch=" >nul && set ARCH=%~1
echo %~1 | findstr /C:"--arch=" >nul && set ARCH=!ARCH:--arch=!
if "%~1"=="--dry-run" set DRY_RUN=1
if "%~1"=="-v" set VERBOSE=1
if "%~1"=="--verbose" set VERBOSE=1
if "%~1"=="-h" goto show_help
if "%~1"=="--help" goto show_help
shift
goto parse_args

:show_help
echo Usage: %0 [options]
echo Options:
echo   --region=cn^|global    Region selection (default: global)
echo   --arch=x64^|arm64     Architecture (default: auto-detected)
echo   --dry-run             Show commands without executing
echo   -v, --verbose        Enable verbose output
echo   -h, --help           Show this help message
exit /b 0

:done_parsing

REM Normalize architecture names
if /i "%ARCH%"=="AMD64" set ARCH=x64
if /i "%ARCH%"=="x86" set ARCH=x64
if /i "%ARCH%"=="ARM64" set ARCH=arm64

REM Function to execute or dry-run
run_cmd:
if "%DRY_RUN%"=="1" (
    echo [DRY RUN] %*
) else (
    if "%VERBOSE%"=="1" echo Executing: %*
    %*
)
exit /b

REM Check and install .NET
echo Checking .NET runtime...
where dotnet >nul 2>&1
if %ERRORLEVEL% EQU 0 (
    for /f "delims=" %%i in ('dotnet --version 2^>nul') do set DOTNET_VERSION=%%i
    echo [OK] .NET runtime already installed: !DOTNET_VERSION!
) else (
    echo [NOT FOUND] .NET runtime not found, installing...
    if "%DRY_RUN%"=="0" (
        if "%VERBOSE%"=="1" echo Executing: winget install Microsoft.DotNet.SDK.10 --silent ...
        winget install Microsoft.DotNet.SDK.10 --silent --accept-source-agreements --accept-package-agreements
    )
    if %ERRORLEVEL% EQU 0 (
        echo [OK] .NET runtime installed
        set /a INSTALLED_COUNT=!INSTALLED_COUNT!+1
    ) else (
        echo [ERROR] Failed to install .NET runtime
        set /a FAILED_COUNT=!FAILED_COUNT!+1
    )
)

REM Check and install Node.js
echo.
echo Checking Node.js...
where node >nul 2>&1
if %ERRORLEVEL% EQU 0 (
    for /f "delims=" %%i in ('node --version 2^>nul') do set NODE_VERSION=%%i
    echo [OK] Node.js already installed: !NODE_VERSION!
) else (
    echo [NOT FOUND] Node.js not found, installing...
    if "%DRY_RUN%"=="0" (
        if "%VERBOSE%"=="1" echo Executing: winget install OpenJS.NodeJS.LTS --silent ...
        winget install OpenJS.NodeJS.LTS --silent --accept-source-agreements --accept-package-agreements
    )
    if %ERRORLEVEL% EQU 0 (
        echo [OK] Node.js installed
        set /a INSTALLED_COUNT=!INSTALLED_COUNT!+1
    ) else (
        echo [ERROR] Failed to install Node.js
        set /a FAILED_COUNT=!FAILED_COUNT!+1
    )
)

REM Check and install NPM
echo.
echo Checking NPM...
where npm >nul 2>&1
if %ERRORLEVEL% EQU 0 (
    for /f "delims=" %%i in ('npm --version 2^>nul') do set NPM_VERSION=%%i
    echo [OK] NPM already installed: v!NPM_VERSION!
) else (
    echo [NOT FOUND] NPM not found, installing...

    REM Ensure Node.js is available
    where node >nul 2>&1
    if %ERRORLEVEL% NEQ 0 (
        echo [ERROR] Node.js not available. Please install Node.js first.
        set /a FAILED_COUNT=!FAILED_COUNT!+1
    ) else (
        if "%REGION%"=="china" (
            set NPM_REGISTRY=--registry=https://registry.npmmirror.com
        ) else (
            set NPM_REGISTRY=
        )

        REM Use recommended version for installation
        set "NPM_INSTALL_VERSION=!NPM_RECOMMENDED_VERSION!"

        if "%DRY_RUN%"=="0" (
            if "%VERBOSE%"=="1" echo Executing: npm install npm@!NPM_INSTALL_VERSION! -g !NPM_REGISTRY! --silent --quiet
            call npm install npm@!NPM_INSTALL_VERSION! -g !NPM_REGISTRY! --silent --quiet
        )

        where npm >nul 2>&1
        if %ERRORLEVEL% EQU 0 (
            echo [OK] NPM installed
            set /a INSTALLED_COUNT=!INSTALLED_COUNT!+1
        ) else (
            echo [ERROR] Failed to install NPM
            set /a FAILED_COUNT=!FAILED_COUNT!+1
        )
    )
)

REM Check and install Claude Code (optional)
echo.
echo Checking Claude Code (optional)...
where claude >nul 2>&1
if %ERRORLEVEL% EQU 0 (
    for /f "delims=" %%i in ('claude --version 2^>nul') do set CLAUDE_VERSION=%%i
    echo [OK] Claude Code already installed: !CLAUDE_VERSION!
) else (
    echo [WARNING] Claude Code not found ^(optional^), installing...

    REM Check if npm is available
    where npm >nul 2>&1
    if %ERRORLEVEL% NEQ 0 (
        echo [WARNING] NPM not available, skipping Claude Code installation
    ) else (
        if "%REGION%"=="china" (
            set NPM_REGISTRY=--registry=https://registry.npmmirror.com
        ) else (
            set NPM_REGISTRY=
        )

        if "%DRY_RUN%"=="0" (
            if "%VERBOSE%"=="1" echo Executing: npm install @anthropic-ai/claude-code@latest -g !NPM_REGISTRY! --silent --quiet
            call npm install @anthropic-ai/claude-code@latest -g !NPM_REGISTRY! --silent --quiet
        )

        where claude >nul 2>&1
        if %ERRORLEVEL% EQU 0 (
            echo [OK] Claude Code installed
            set /a INSTALLED_COUNT=!INSTALLED_COUNT!+1
        ) else (
            echo [WARNING] Failed to install Claude Code
        )
    )
)

REM Check and install OpenSpec (optional)
echo.
echo Checking OpenSpec (optional)...
where openspec >nul 2>&1
if %ERRORLEVEL% EQU 0 (
    for /f "delims=" %%i in ('openspec --version 2^>nul') do set OPENSPEC_VERSION=%%i
    echo [OK] OpenSpec already installed: !OPENSPEC_VERSION!
) else (
    echo [WARNING] OpenSpec not found ^(optional^), installing...

    REM Check if npm is available
    where npm >nul 2>&1
    if %ERRORLEVEL% NEQ 0 (
        echo [WARNING] NPM not available, skipping OpenSpec installation
    ) else (
        if "%REGION%"=="china" (
            set NPM_REGISTRY=--registry=https://registry.npmmirror.com
        ) else (
            set NPM_REGISTRY=
        )

        REM Install OpenSpec at minimum version
        if "%DRY_RUN%"=="0" (
            if "%VERBOSE%"=="1" echo Executing: npm install @fission-ai/openspec@%OPENSPEC_MIN_VERSION% -g !NPM_REGISTRY! --silent --quiet
            call npm install @fission-ai/openspec@%OPENSPEC_MIN_VERSION% -g !NPM_REGISTRY! --silent --quiet
        )

        where openspec >nul 2>&1
        if %ERRORLEVEL% EQU 0 (
            echo [OK] OpenSpec installed
            set /a INSTALLED_COUNT=!INSTALLED_COUNT!+1
        ) else (
            echo [WARNING] Failed to install OpenSpec
        )
    )
)

REM Summary
echo.
echo === Installation Summary ===
echo Components installed/updated: !INSTALLED_COUNT!
echo Components failed: !FAILED_COUNT!

if "%DRY_RUN%"=="1" (
    echo [DRY RUN] No actual changes made
) else (
    echo [OK] Installation completed
)

REM Optional: Generate JSON result file if requested
if "%~1"=="--json" (
    echo.
    echo Generating installation result JSON...
    REM Get current timestamp in ISO format
    for /f "tokens=2 delims==" %%a in ('wmic os get localdatetime /value') do set "dt=%%a"
    set TIMESTAMP=%dt:~0,4%-%dt:~4,2%-%dt:~6,2%T%dt:~8,2%:%dt:~10,2%:%dt:~12,2%Z

    REM Escape paths for JSON (if any paths were captured)
    REM This is a template for future JSON output capability
    REM Currently the script only captures counts, not individual paths

    (
    echo {
    echo   "timestamp": "%TIMESTAMP%",
    echo   "platform": "windows",
    echo   "installedCount": !INSTALLED_COUNT!,
    echo   "failedCount": !FAILED_COUNT!,
    echo   "dryRun": %DRY_RUN%
    echo }
    ) > install-result.json
    echo Installation result written to: install-result.json
)

endlocal
exit /b 0
