@echo off
setlocal EnableExtensions EnableDelayedExpansion
cd ../ruoyi-admin/target

set "SCRIPT_DIR=%~dp0"
if "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"

set "APP_NAME=ruoyi-admin.jar"
set "JAVA_EXE=%JAVA_EXE%"
if not defined JAVA_EXE set "JAVA_EXE=java"
set "JPS_EXE=%JPS_EXE%"
if not defined JPS_EXE set "JPS_EXE=jps"
set "MVN_EXE=%MVN_EXE%"
if not defined MVN_EXE set "MVN_EXE=mvn"
set "MVN_ARGS=-pl ruoyi-admin -am package -DskipTests"
set "JVM_OPTS=-Dname=%APP_NAME% -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC"
set "DRY_RUN="
if /I "%RY_DRY_RUN%"=="1" set "DRY_RUN=1"
if /I "%~2"=="--dry-run" set "DRY_RUN=1"

if /I "%~1"=="start" goto start
if /I "%~1"=="stop" goto stop
if /I "%~1"=="restart" goto restart
if /I "%~1"=="status" goto status
if /I "%~1"=="help" goto help
if not "%~1"=="" goto help

:menu
ECHO.
ECHO.  [1] Start %APP_NAME%
ECHO.  [2] Stop %APP_NAME%
ECHO.  [3] Restart %APP_NAME%
ECHO.  [4] Status %APP_NAME%
ECHO.  [5] Exit
ECHO.
ECHO.Select an action:
set /p ID=
if /I "%ID%"=="1" goto start
if /I "%ID%"=="2" goto stop
if /I "%ID%"=="3" goto restart
if /I "%ID%"=="4" goto status
if /I "%ID%"=="5" exit /b 0
echo Invalid selection.
pause
goto menu

:help
echo Usage: ry.bat ^<start^|stop^|restart^|status^> [--dry-run]
exit /b 1

:resolveAppPath
set "APP_PATH=%SCRIPT_DIR%\%APP_NAME%"
if exist "%APP_PATH%" exit /b 0
set "APP_PATH=%SCRIPT_DIR%\ruoyi-admin\target\%APP_NAME%"
if exist "%APP_PATH%" exit /b 0
set "APP_PATH="
exit /b 1

:shouldPackageJar
set "NEED_PACKAGE="
if not exist "%SCRIPT_DIR%\pom.xml" exit /b 0
if not exist "%SCRIPT_DIR%\ruoyi-admin\pom.xml" exit /b 0
if exist "%SCRIPT_DIR%\ruoyi-admin\target\%APP_NAME%.original" exit /b 0
set "NEED_PACKAGE=1"
exit /b 0

:findProcess
set "pid="
set "image_name="
for /f "tokens=1,*" %%a in ('%JPS_EXE% -l ^| findstr /I /C:"%APP_NAME%"') do (
    set "pid=%%a"
    set "image_name=%%b"
    goto findProcessDone
)
:findProcessDone
exit /b 0

:start
call :shouldPackageJar
if defined NEED_PACKAGE (
    if defined DRY_RUN echo BUILD_CMD=%MVN_EXE% %MVN_ARGS%
    if not defined DRY_RUN (
        echo Packaging executable jar for %APP_NAME%...
        pushd "%SCRIPT_DIR%"
        call %MVN_EXE% %MVN_ARGS%
        set "build_exit=!ERRORLEVEL!"
        popd
        if not "!build_exit!"=="0" exit /b !build_exit!
    )
)

call :resolveAppPath
if errorlevel 1 (
    echo [ERROR] Unable to find %APP_NAME%.
    echo Checked:
    echo   %SCRIPT_DIR%\%APP_NAME%
    echo   %SCRIPT_DIR%\ruoyi-admin\target\%APP_NAME%
    exit /b 1
)

call :findProcess
if defined pid (
    echo %APP_NAME% is already running. PID=!pid!
    exit /b 0
)

if defined DRY_RUN (
    echo START_CMD=%JAVA_EXE% %JVM_OPTS% -jar "%APP_PATH%"
    exit /b 0
)

echo Starting %APP_NAME%...
%JAVA_EXE% %JVM_OPTS% -jar "%APP_PATH%"
exit /b %ERRORLEVEL%

:stop
call :findProcess
if not defined pid (
    echo process %APP_NAME% does not exist
    exit /b 0
)

echo Stopping %APP_NAME% (PID !pid! )...
taskkill /f /pid !pid! >nul 2>nul
if errorlevel 1 (
    echo [ERROR] Failed to stop %APP_NAME%.
    exit /b 1
)

echo %APP_NAME% stopped.
exit /b 0

:restart
call :stop
if errorlevel 1 exit /b 1
call :start
exit /b %ERRORLEVEL%

:status
call :findProcess
if not defined pid (
    echo process %APP_NAME% is dead
    exit /b 0
)

echo %image_name% is running with PID !pid!
exit /b 0
