@echo off
setlocal EnableDelayedExpansion
REM Run OHOS app and debug on Windows (paths and commands differ from Mac)
REM Usage: runDebugOhosApp-Win.bat [options] [PLATFORM] [TARGET_ID]
REM   Options: -b BUNDLE -a ABILITY -p LOCAL_OHOS_PATH
REM   Example: runDebugOhosApp-Win.bat ohosArm64 127.0.0.1:5555

set DEFAULT_PLATFORM=ohosArm64
set DEFAULT_TARGET_ID=127.0.0.1:5555
set DEFAULT_BUNDLE_NAME=com.example.harmonyapp
set DEFAULT_ABILITY_NAME=EntryAbility
set BUNDLE_NAME=%DEFAULT_BUNDLE_NAME%
set ABILITY_NAME=%DEFAULT_ABILITY_NAME%
set BUILD_MODE=debug
set DEBUG_MODE=attach
set LOCAL_OHOS_PATH=
set PLATFORM=
set TARGET_ID=

REM Parse options (supports options in any position, e.g. ohosArm64 62Q0226107024702 -m release)
:parse
if "%~1"=="" goto done_parse
if "%~1"=="-m" (set "BUILD_MODE=%~2" & shift & shift & goto parse)
if "%~1"=="-b" (set "BUNDLE_NAME=%~2" & shift & shift & goto parse)
if "%~1"=="-a" (set "ABILITY_NAME=%~2" & shift & shift & goto parse)
if "%~1"=="-d" (set "DEBUG_MODE=%~2" & shift & shift & goto parse)
if "%~1"=="-p" (set "LOCAL_OHOS_PATH=%~2" & shift & shift & goto parse)
if "%~1"=="-h" goto show_help
REM Positional: first=PLATFORM, second=TARGET_ID
if "!PLATFORM!"=="" (set "PLATFORM=%~1") else if "!TARGET_ID!"=="" (set "TARGET_ID=%~1")
shift
goto parse
:done_parse
if "!PLATFORM!"=="" set "PLATFORM=%DEFAULT_PLATFORM%"
if "!TARGET_ID!"=="" set "TARGET_ID=%DEFAULT_TARGET_ID%"

REM Record script start time (epoch seconds for elapsed calculation)
for /f %%t in ('powershell -NoProfile -Command "[int][double]::Parse((Get-Date -UFormat '%%s'))"') do set START_TIME=%%t

echo Run environment configuration:
echo   - Platform: %PLATFORM%
echo   - Device: %TARGET_ID%
echo   - Build mode: %BUILD_MODE%
echo   - Debug mode: %DEBUG_MODE%
echo   - Bundle: %BUNDLE_NAME%
echo   - Ability: %ABILITY_NAME%
if not "%LOCAL_OHOS_PATH%"=="" echo   - External OHOS path: %LOCAL_OHOS_PATH%
echo ------------------------------------------------------------

REM ====================== [2. Environment Path and SDK Configuration] ======================
REM DevEco/SDK path: OHOS_SDK_HOME env or default Windows location
if not "%OHOS_SDK_HOME%"=="" (
  set "SDK_HOME=%OHOS_SDK_HOME%"
) else (
  if exist "C:\Program Files\Huawei\DevEco Studio" (
    set "SDK_HOME=C:\Program Files\Huawei\DevEco Studio"
  ) else if exist "D:\Program Files\Huawei\DevEco Studio" (
    set "SDK_HOME=D:\Program Files\Huawei\DevEco Studio"
  ) else (
    echo Error: DevEco Studio not found. Set OHOS_SDK_HOME or install to default path.
    exit /b 1
  )
)
echo DevEco Studio Path: %SDK_HOME%
echo Checking environment configuration...

set "MIN_VERSION=6.0.0"
set "PRODUCT_INFO=%SDK_HOME%\product-info.json"
if exist "%PRODUCT_INFO%" (
  for /f "tokens=*" %%v in ('powershell -NoProfile -Command "(Get-Content '%PRODUCT_INFO%' | ConvertFrom-Json).version"') do set "CURRENT_VERSION=%%v"
) else (
  echo Warning: product-info.json not found, skipping version check.
  set "CURRENT_VERSION=unknown"
)

if not "%CURRENT_VERSION%"=="unknown" (
  echo Current DevEco version: %CURRENT_VERSION%
  echo Minimum required version: %MIN_VERSION%
  for /f "tokens=1,2 delims=." %%a in ("%CURRENT_VERSION%") do (
    set "CUR_MAJOR=%%a"
    set "CUR_MINOR=%%b"
  )
  for /f "tokens=1,2 delims=." %%a in ("%MIN_VERSION%") do (
    set "REQ_MAJOR=%%a"
    set "REQ_MINOR=%%b"
  )
  if !CUR_MAJOR! lss !REQ_MAJOR! (
    echo -------------------------------------------------------
    echo Error: DevEco version is too low!
    echo Current version: %CURRENT_VERSION%
    echo Minimum required: %MIN_VERSION%+
    echo Please upgrade DevEco Studio and run this script again.
    echo -------------------------------------------------------
    exit /b 5
  )
  if !CUR_MAJOR! equ !REQ_MAJOR! if !CUR_MINOR! lss !REQ_MINOR! (
    echo -------------------------------------------------------
    echo Error: DevEco version is too low!
    echo Current version: %CURRENT_VERSION%
    echo Minimum required: %MIN_VERSION%+
    echo Please upgrade DevEco Studio and run this script again.
    echo -------------------------------------------------------
    exit /b 5
  )
  echo DevEco version meets requirements (%CURRENT_VERSION%)
)

set "HDC_BIN=%SDK_HOME%\sdk\default\openharmony\toolchains\hdc.exe"
set "DEVECO_SDK_HOME=%SDK_HOME%\sdk"
set "PATH=%SDK_HOME%\tools\node;%SDK_HOME%\tools\ohpm\bin;%SDK_HOME%\tools\hvigor\bin;%DEVECO_SDK_HOME%;%PATH%"

if not exist "%HDC_BIN%" (
  echo Error: hdc not found at %HDC_BIN%
  exit /b 1
)

"%HDC_BIN%" -t %TARGET_ID% shell aa force-stop %BUNDLE_NAME% 2>nul
REM ====================== Gradle Build ======================
echo Working path: %CD%
echo Building OpenHarmony (%PLATFORM%)...

if "%PLATFORM%"=="ohosArm64" (
   REM for ohosArm64 ohos in windows x86_64 build
  if "%BUILD_MODE%"=="release" (
    if not "%LOCAL_OHOS_PATH%"=="" (
      call gradlew.bat :composeApp:publishReleaseBinariesToHarmonyApp -PharmonyAppPath="%LOCAL_OHOS_PATH%"
    ) else (
      call gradlew.bat :composeApp:publishReleaseBinariesToHarmonyApp
    )
  ) else (
    if not "%LOCAL_OHOS_PATH%"=="" (
      call gradlew.bat :composeApp:publishDebugBinariesToHarmonyApp -PharmonyAppPath="%LOCAL_OHOS_PATH%"
    ) else (
      call gradlew.bat :composeApp:publishDebugBinariesToHarmonyApp
    )
  )
) else if "%PLATFORM%"=="ohosX86_64" (
    REM  for simulate ohos in windows x86_64
  if "%BUILD_MODE%"=="release" (
    if not "%LOCAL_OHOS_PATH%"=="" (
      call gradlew.bat :composeApp:publishReleaseBinariesToHarmonyAppX64 -PharmonyAppPath="%LOCAL_OHOS_PATH%"
    ) else (
      call gradlew.bat :composeApp:publishReleaseBinariesToHarmonyAppX64
    )
  ) else (
    if not "%LOCAL_OHOS_PATH%"=="" (
      call gradlew.bat :composeApp:publishDebugBinariesToHarmonyAppX64 -PharmonyAppPath="%LOCAL_OHOS_PATH%"
    ) else (
      call gradlew.bat :composeApp:publishDebugBinariesToHarmonyAppX64
    )
  )
) else (
  echo Error: Unsupported platform '%PLATFORM%'
  exit /b 4
)

if errorlevel 1 exit /b %errorlevel%

REM SO packaging end time / HAP build start time
for /f %%t in ('powershell -NoProfile -Command "[int][double]::Parse((Get-Date -UFormat '%%s'))"') do set HAP_START_TIME=%%t

REM ====================== HAP build ======================
if not "%LOCAL_OHOS_PATH%"=="" (
  set "HARMONY_APP_DIR=%LOCAL_OHOS_PATH%"
) else (
  set "HARMONY_APP_DIR=harmonyApp"
)

if not exist "%HARMONY_APP_DIR%" (
  echo Error: harmonyApp directory not found: %HARMONY_APP_DIR%
  exit /b 4
)

cd /d "%HARMONY_APP_DIR%"
echo Switched to harmonyApp directory: %CD%
echo Running ohpm and Hvigor...

call ohpm install --all
if errorlevel 1 (echo ohpm install failed & exit /b 1)

call node "%SDK_HOME%\tools\hvigor\bin\hvigorw.js" --sync -p product=default -p buildMode=%BUILD_MODE% --analyze=normal --parallel --incremental --daemon
if "%BUILD_MODE%"=="release" (
  call node "%SDK_HOME%\tools\hvigor\bin\hvigorw.js" --mode module -p module=entry -p product=default -p buildMode=release -p requiredDeviceType=phone assembleHap compileNative --analyze=normal --parallel --incremental --daemon
) else (
  call node "%SDK_HOME%\tools\hvigor\bin\hvigorw.js" --mode module -p module=entry@default -p product=default -p buildMode=debug -p requiredDeviceType=phone assembleHap --analyze=normal --parallel --incremental --daemon
)
if errorlevel 1 (echo Hvigor build failed & exit /b 1)

REM ====================== Install HAP ======================
set "HAP_DIR=entry\build\default\outputs\default"
set "SIGNED_HAP=entry-default-signed.hap"
set "HAP_FILE=%HAP_DIR%\%SIGNED_HAP%"

if not exist "%HAP_FILE%" (
  echo Error: Signed HAP package not found!
  echo.
  echo Expected path: %HARMONY_APP_DIR%\%HAP_DIR%\%SIGNED_HAP%
  echo.
  echo Possible causes: build not done, build failed, or HAP not signed.
  echo Suggested: check build logs, verify signing in DevEco Studio.
  exit /b 6
)

set DEVICE_FOUND=
for /f "delims=" %%i in ('"%HDC_BIN%" list targets 2^>nul') do echo %%i | findstr /C:"%TARGET_ID%" >nul && set DEVICE_FOUND=1
if not defined DEVICE_FOUND (
  echo Error: Device %TARGET_ID% is offline!
  exit /b 5
)

echo Pushing debug components and installing HAP...
echo   - Device: %TARGET_ID%
set "REMOTE_HAP_DIR=/data/local/tmp/debug_install"
set "REMOTE_HAP_PATH=%REMOTE_HAP_DIR%/%SIGNED_HAP%"
"%HDC_BIN%" -t %TARGET_ID% shell mkdir -p %REMOTE_HAP_DIR%
"%HDC_BIN%" -t %TARGET_ID% file send "%HAP_FILE%" %REMOTE_HAP_DIR%

"%HDC_BIN%" -t %TARGET_ID% shell bm install -p "%REMOTE_HAP_PATH%" 2>nul
if errorlevel 1 (
  echo Reinstall: uninstall then install again...
  "%HDC_BIN%" -t %TARGET_ID% shell bm uninstall -n %BUNDLE_NAME% 2>nul
  timeout /t 5 /nobreak >nul
  "%HDC_BIN%" -t %TARGET_ID% shell bm install -p "%REMOTE_HAP_PATH%"
  timeout /t 5 /nobreak >nul
)

REM ====================== Launch and LLDB ======================
"%HDC_BIN%" -t %TARGET_ID% shell rm -rf %REMOTE_HAP_DIR%
timeout /t 1 /nobreak >nul
echo Launching app and starting debug listener...
echo   If device screen is locked, please unlock it manually.
echo.
if "%DEBUG_MODE%"=="debug" (
  echo   Debug mode, starting with -D flag
  "%HDC_BIN%" -t %TARGET_ID% shell aa start -a %ABILITY_NAME% -b %BUNDLE_NAME% -D
) else (
  echo   Attach mode, starting without -D flag
  "%HDC_BIN%" -t %TARGET_ID% shell aa start -a %ABILITY_NAME% -b %BUNDLE_NAME%
)
REM Package push complete time
for /f %%t in ('powershell -NoProfile -Command "[int][double]::Parse((Get-Date -UFormat '%%s'))"') do set END_TIME=%%t
"%HDC_BIN%" -t %TARGET_ID% shell rm -rf /data/local/tmp/debugserver/lldb-server
"%HDC_BIN%" -t %TARGET_ID% shell mkdir -p /data/local/tmp/debugserver
"%HDC_BIN%" -t %TARGET_ID% file send "%SDK_HOME%\sdk\default\hms\native\lldb\aarch64-linux-ohos\lldb-server" /data/local/tmp/debugserver/
"%HDC_BIN%" -t %TARGET_ID% shell chmod 755 /data/local/tmp/debugserver/lldb-server

set /a COUNT=0
:wait_pid
set APP_PID=
for /f "tokens=1" %%i in ('"%HDC_BIN%" -t %TARGET_ID% shell pidof %BUNDLE_NAME% 2^>nul') do set "APP_PID=%%i"
if not "%APP_PID%"=="" goto got_pid
timeout /t 1 /nobreak >nul
set /a COUNT+=1
if %COUNT% lss 25 goto wait_pid
echo Error: App did not start within expected time
exit /b 1
:got_pid

echo App started (PID: %APP_PID%)
"%HDC_BIN%" -t %TARGET_ID% shell aa attach -b %BUNDLE_NAME%
"%HDC_BIN%" -t %TARGET_ID% shell aa process -a %ABILITY_NAME% -b %BUNDLE_NAME% -D "/data/local/tmp/debugserver/lldb-server platform --listen unix-abstract:///lldb-server/platform.sock"

echo ------------------------------------------------------------
echo Build, install and app launch completed!
echo.
echo App info:
echo   - Bundle: %BUNDLE_NAME%
echo   - PID: %APP_PID%
echo   - Device: %TARGET_ID%
set /a ELAPSED=HAP_START_TIME-START_TIME
set /a MINUTES=ELAPSED/60
set /a SECONDS=ELAPSED%%60
echo   - SO build time: !MINUTES!m!SECONDS!s (!ELAPSED!s)
set /a ELAPSED=END_TIME-HAP_START_TIME
set /a MINUTES=ELAPSED/60
set /a SECONDS=ELAPSED%%60
echo   - HAP package and push time: !MINUTES!m!SECONDS!s (!ELAPSED!s)
set /a ELAPSED=END_TIME-START_TIME
set /a MINUTES=ELAPSED/60
set /a SECONDS=ELAPSED%%60
echo   - Total time: !MINUTES!m!SECONDS!s (!ELAPSED!s)
echo Note: You can now connect via LLDB to debug on the device
echo ------------------------------------------------------------

:show_help
echo Usage: %~nx0 [options] [PLATFORM] [TARGET_ID]
echo.
echo Parameters:
echo   PLATFORM    Build platform (default: %DEFAULT_PLATFORM%)
echo   TARGET_ID   Device ID (default: %DEFAULT_TARGET_ID%)
echo.
echo Options:
echo   -m MODE    Build mode: debug or release (default: debug)
echo   -b BUNDLE   Set bundle name (current: %DEFAULT_BUNDLE_NAME%)
echo   -a ABILITY  Set Ability name (current: %DEFAULT_ABILITY_NAME%)
echo   -d MODE     Debug mode: debug or attach (default: attach)
echo   -p PATH     Set external OHOS project path (localOhosPath)
echo   -h          Show this help
echo.
echo Examples:
echo   %~nx0 ohosArm64 127.0.0.1:5555
echo   %~nx0 -m release
echo   %~nx0 -b com.test.app -a MainAbility
echo   %~nx0 -p D:\path\to\external\ohos\project
exit /b 0
