@echo off
setlocal enabledelayedexpansion
:: ========================================
:: Cyrene ethend CLI (Windows CMD)
:: Usage: ethend.bat [command] [options]
:: ========================================

set "SCRIPT_DIR=%~dp0"
set "ETHEND_DIR=%SCRIPT_DIR%ethend"
set "ROOT=%SCRIPT_DIR%"
if "%ETHEND_PORT%"=="" (set ETHEND_PORT=9090) else (set ETHEND_PORT=%ETHEND_PORT%)
set "LOG_DIR=%ETHEND_DIR%\logs"
set "LOG_FILE=%LOG_DIR%\sh.log"
set "DB_COMPOSE_FILE=%ROOT%docker-compose.dev.db.yml"

:: Parse first argument as command
set CMD=%1
if "%CMD%"=="" set CMD=start
if "%CMD%"=="help" goto :help
if "%CMD%"=="--help" goto :help
if "%CMD%"=="/?" goto :help
if "%CMD%"=="start" goto :start
if "%CMD%"=="stop" goto :stop
if "%CMD%"=="status" goto :status
if "%CMD%"=="logs" goto :logs
if "%CMD%"=="build" goto :build
if "%CMD%"=="db:start" goto :db_start
if "%CMD%"=="db:stop" goto :db_stop
if "%CMD%"=="db:status" goto :db_status

echo [ERROR] Unknown command: %CMD%
echo.
goto :help

:: ==========================================
:help
echo Cyrene ethend - Development Management Tool
echo.
echo Usage: ethend.bat [command] [options]
echo.
echo Commands:
echo   start              Start ethend console (default)
echo   start --build      Build all services before start
echo   start --fresh      Force restart all services before start
echo   stop               Stop ethend console
echo   status             Show all service status
echo   logs [service]      View service logs (default: last 20 lines)
echo   build [service]     Build service(s) (omit to build all)
echo   db:start           Start database containers
echo   db:stop            Stop database containers
echo   db:status          Check database connection status
echo   help               Show this help
echo.
echo Options:
echo   --build             Build all backend services before start
echo   --fresh             Force restart all services before start
echo.
echo Examples:
echo   ethend.bat                           Quick start
echo   ethend.bat start --build             Build and start
echo   ethend.bat start --fresh             Fresh restart
echo   ethend.bat logs gateway              View Gateway log
echo   ethend.bat build ai-core             Build AI-Core only
echo   ethend.bat db:status                 Check database
echo.
echo Web console: http://localhost:%ETHEND_PORT%
exit /b 0

:: ==========================================
:check_node
where node >nul 2>&1
if %ERRORLEVEL%==0 (
    set NODE_CMD=node
    goto :eof
)
if exist "C:\Program Files\nodejs\node.exe" (
    set "NODE_CMD=C:\Program Files\nodejs\node.exe"
    goto :eof
)
echo [ERROR] Node.js not found. Install Node.js 20+ and add to PATH.
pause
exit /b 1

:: ==========================================
:start
:: Ensure log directory
if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"

echo.
echo ==========================================
echo   Cyrene ethend
echo ==========================================
echo %date% %time% ethend.bat started >> "%LOG_FILE%"
call :check_node
for /f "tokens=*" %%i in ('!NODE_CMD! --version') do echo Node.js: %%i
echo Port: %ETHEND_PORT%

:: Check for --build / --fresh
set DO_BUILD=0
set DO_FRESH=0
for %%a in (%*) do (
    if "%%a"=="--build" set DO_BUILD=1
    if "%%a"=="--fresh" set DO_FRESH=1
)

:: Build if requested
if %DO_BUILD%==1 (
    echo.
    echo [INFO] Building all backend services...
    call :build_all
)

:: Fresh restart if requested
if %DO_FRESH%==1 (
    echo.
    echo [INFO] Force restarting all services...
    curl -s -X POST "http://localhost:%ETHEND_PORT%/api/services/start-all-fresh" >nul 2>&1
)

:: Check if port already in use
set FOUND_PID=
for /f "tokens=5" %%a in ('netstat -ano ^| findstr /R ":%ETHEND_PORT% " ^| findstr "LISTENING"') do set FOUND_PID=%%a
if not "%FOUND_PID%"=="" (
    echo.
    echo [WARN] Port %ETHEND_PORT% is in use by PID %FOUND_PID%.
    set /p CHOICE="Kill old process and restart? [Y/n]: "
    if /i "!CHOICE!"=="n" (
        echo [INFO] Aborted by user.
        pause
        exit /b 0
    )
    echo [INFO] Killing PID %FOUND_PID%...
    taskkill /PID %FOUND_PID% /F >nul 2>&1
    timeout /t 2 /nobreak >nul
)

cd /d "%ETHEND_DIR%"

:: Install dependencies
if not exist "node_modules\" (
    echo [INFO] Installing dependencies...
    call npm install --silent
)

echo.
echo [INFO] Starting ethend on port %ETHEND_PORT%
echo   Web UI:  http://localhost:%ETHEND_PORT%
echo   API:     http://localhost:%ETHEND_PORT%/api/health
echo   WebSocket: ws://localhost:%ETHEND_PORT%/ws
echo.

start "Cyrene-ethend" /B !NODE_CMD! src\index.js 1>>"%LOG_FILE%" 2>&1

:: Health check (up to 30s)
echo [INFO] Waiting for ethend to be ready...
set MAX_WAIT=30
set WAITED=0
:health_loop
if %WAITED% geq %MAX_WAIT% goto :timeout
powershell -Command "try { (Invoke-WebRequest 'http://localhost:%ETHEND_PORT%/api/health' -TimeoutSec 2 -UseBasicParsing).StatusCode -eq 200 } catch { $false }" | findstr "True" >nul 2>&1
if %ERRORLEVEL%==0 (
    echo.
    echo ==========================================
    echo   ethend is ready!
    echo   Console: http://localhost:%ETHEND_PORT%
    echo   Log:     %LOG_FILE%
    echo ==========================================
    echo.
    exit /b 0
)
timeout /t 1 /nobreak >nul
set /a WAITED+=1
goto :health_loop

:timeout
echo.
echo [WARN] Still starting - waited %MAX_WAIT%s
echo        Check http://localhost:%ETHEND_PORT%/api/health
exit /b 0

:: ==========================================
:stop
for /f "tokens=5" %%a in ('netstat -ano ^| findstr /R ":%ETHEND_PORT% " ^| findstr "LISTENING"') do (
    echo [INFO] Stopping ethend (PID: %%a)...
    taskkill /PID %%a /F >nul 2>&1
    echo [OK] ethend stopped
    exit /b 0
)
echo [INFO] ethend is not running
exit /b 0

:: ==========================================
:status
curl -s -o nul "http://localhost:%ETHEND_PORT%/api/health" 2>nul
if %ERRORLEVEL% neq 0 (
    echo [ERROR] ethend is offline
    exit /b 1
)
echo [OK] ethend online
echo.
echo Service Status:
curl -s "http://localhost:%ETHEND_PORT%/api/services" 2>nul | !NODE_CMD! -e "const d=require('fs').readFileSync(0,'utf-8');const s=JSON.parse(d);for(const[k,v]of Object.entries(s)){const icon=v.status==='running'?'+':' ';const pid=v.pid?' (PID:'+v.pid+')':'';const upt=v.uptime?' uptime:'+Math.round(v.uptime/1000)+'s':'';console.log('  ['+icon+'] '+v.name.padEnd(18)+v.status+pid+upt);}" 2>nul
echo.
echo Database:
powershell -Command "$tcp=New-Object Net.Sockets.TcpClient;try{$tcp.Connect('127.0.0.1',5432);'  [OK] PostgreSQL online'}catch{'  [--] PostgreSQL offline'};$tcp.Dispose()" 2>nul
exit /b 0

:: ==========================================
:logs
set SVC_ID=%2
set LINES=%3
if "%SVC_ID%"=="" (
    echo Usage: ethend.bat logs ^<service-id^> [lines]
    echo Available: gateway, ai-core, memory-service, tool-engine, voice-service, iot-debug-service, plugin-manager, platform-bridge, frontend
    exit /b 1
)
if "%LINES%"=="" set LINES=20
set "LOG_PATH=%LOG_DIR%\%SVC_ID%.log"
if not exist "%LOG_PATH%" (
    echo [WARN] Log file not found: %LOG_PATH%
    exit /b 1
)
echo === %SVC_ID% log (last %LINES% lines) ===
powershell -Command "Get-Content '%LOG_PATH%' -Tail %LINES%" 2>nul
exit /b 0

:: ==========================================
:build
call :check_node
set SVC_ID=%2
if not "%SVC_ID%"=="" goto :build_one

:build_all
echo [INFO] Building all backend services...
set SERVICES=memory-service:backend/memory-service iot-debug-service:backend/iot-debug-service voice-service:backend/voice-service ai-core:backend/ai-core plugin-manager:backend/cyrene-plugins platform-bridge:backend/platform-bridge gateway:backend/gateway
for %%s in (%SERVICES%) do (
    for /f "tokens=1,2 delims=:" %%a in ("%%s") do (
        if exist "%ROOT%%%b" (
            echo   Building %%a...
            cd /d "%ROOT%%%b"
            set GOWORK=off
            if "%%a"=="plugin-manager" (
                go build -o main.exe .\cmd\plugin-manager\ 2>&1
            ) else (
                go build -o main.exe .\cmd\main.go 2>&1
            )
            if !ERRORLEVEL!==0 (
                echo     [OK] %%a
            ) else (
                echo     [FAIL] %%a
            )
        )
    )
)
cd /d "%ROOT%"
echo [OK] Build complete
exit /b 0

:build_one
for %%s in (memory-service:backend/memory-service iot-debug-service:backend/iot-debug-service voice-service:backend/voice-service ai-core:backend/ai-core plugin-manager:backend/cyrene-plugins platform-bridge:backend/platform-bridge gateway:backend/gateway) do (
    for /f "tokens=1,2 delims=:" %%a in ("%%s") do (
        if "%%a"=="%SVC_ID%" (
            if not exist "%ROOT%%%b" (
                echo [ERROR] Service directory not found: %%b
                exit /b 1
            )
            echo [INFO] Building %%a...
            cd /d "%ROOT%%%b"
            set GOWORK=off
            if "%%a"=="plugin-manager" (
                go build -o main.exe .\cmd\plugin-manager\ 2>&1
            ) else (
                go build -o main.exe .\cmd\main.go 2>&1
            )
            if !ERRORLEVEL!==0 (echo [OK] %%a) else (echo [FAIL] %%a)
            cd /d "%ROOT%"
            exit /b !ERRORLEVEL!
        )
    )
)
echo [ERROR] Unknown service: %SVC_ID%
echo Available: memory-service, iot-debug-service, voice-service, ai-core, plugin-manager, platform-bridge, gateway
exit /b 1

:: ==========================================
:db_start
echo [INFO] Starting database containers...
if not exist "%DB_COMPOSE_FILE%" (
    echo [ERROR] File not found: %DB_COMPOSE_FILE%
    exit /b 1
)
docker compose -f "%DB_COMPOSE_FILE%" up -d
echo [OK] Database containers started
exit /b 0

:: ==========================================
:db_stop
echo [INFO] Stopping database containers...
if not exist "%DB_COMPOSE_FILE%" (
    echo [ERROR] File not found: %DB_COMPOSE_FILE%
    exit /b 1
)
docker compose -f "%DB_COMPOSE_FILE%" down
echo [OK] Database containers stopped
exit /b 0

:: ==========================================
:db_status
powershell -Command "$tcp=New-Object Net.Sockets.TcpClient;try{$tcp.Connect('127.0.0.1',5432);Write-Host '  [OK] PostgreSQL online'}catch{Write-Host '  [--] PostgreSQL offline'};$tcp.Dispose()" 2>nul
exit /b 0
