@echo off
setlocal EnableExtensions EnableDelayedExpansion
title devstart - Development Launcher

:: -----------------------------------------------------------------------------
:: devstart - Launch local development environments from project scripts
:: Usage:  devstart [project]     devstart --list   also: --projects
::         devstart --help        devstart --stay-open [project]
::
:: Aliases:  projects/name.aliases - one alias per line, # = comment
:: -----------------------------------------------------------------------------

set "DEVSTART_VERSION=1.0.0"
set "DEVSTART_ROOT=%~dp0"
if defined DEVSTART_PROJECTS_DIR (
    set "PROJECTS_DIR=%DEVSTART_PROJECTS_DIR%"
) else (
    set "PROJECTS_DIR=%DEVSTART_ROOT%projects"
)

set "EXIT_OK=0"
set "EXIT_USAGE=1"
set "EXIT_NOT_FOUND=2"
set "EXIT_ENV=3"

call :MAIN %*
set "ERC=%ERRORLEVEL%"
if "!DS_HARD_EXIT!"=="1" if %ERC% equ 0 (
    endlocal & exit 0
)
endlocal & exit /b %ERC%

:: =============================================================================
:MAIN
set "QUIET=0"
set "AUTO_CLOSE=1"
set "PROJECT_NAME="
set "PROJECT_SCRIPT="
set "FINISH_RC="

if "%~1"=="" goto SHOW_HELP

:: --- Parse arguments (flags may appear in any order) -------------------------
:PARSE_NEXT
if "%~1"=="" goto PARSE_DONE
if /i "%~1"=="--stay-open" set "AUTO_CLOSE=0" & shift & goto PARSE_NEXT
if /i "%~1"=="--keep-open" set "AUTO_CLOSE=0" & shift & goto PARSE_NEXT
if /i "%~1"=="-k" set "AUTO_CLOSE=0" & shift & goto PARSE_NEXT
if /i "%~1"=="--quiet" set "QUIET=1" & shift & goto PARSE_NEXT
if /i "%~1"=="-q" set "QUIET=1" & shift & goto PARSE_NEXT
if not defined PROJECT_NAME (
    set "PROJECT_NAME=%~1"
    shift
    goto PARSE_NEXT
)
shift
goto PARSE_NEXT

:PARSE_DONE
if not defined PROJECT_NAME goto SHOW_HELP

if /i "!PROJECT_NAME!"=="help" goto SHOW_HELP
if /i "!PROJECT_NAME!"=="--help" goto SHOW_HELP
if /i "!PROJECT_NAME!"=="-h" goto SHOW_HELP
if /i "!PROJECT_NAME!"=="/?" goto SHOW_HELP
if /i "!PROJECT_NAME!"=="list" goto LIST_ONLY
if /i "!PROJECT_NAME!"=="--list" goto LIST_ONLY
if /i "!PROJECT_NAME!"=="-l" goto LIST_ONLY
if /i "!PROJECT_NAME!"=="projects" goto LIST_ONLY
if /i "!PROJECT_NAME!"=="--projects" goto LIST_ONLY
if /i "!PROJECT_NAME!"=="version" goto SHOW_VERSION
if /i "!PROJECT_NAME!"=="--version" goto SHOW_VERSION
if /i "!PROJECT_NAME!"=="-v" goto SHOW_VERSION

goto RUN_PROJECT

:RUN_PROJECT
call :ENSURE_PROJECTS_DIR
if errorlevel 1 exit /b !EXIT_ENV!

call :RESOLVE_PROJECT
if errorlevel 1 goto PROJECT_NOT_FOUND

if not "!QUIET!"=="1" goto RUN_WITH_UI
goto RUN_EXECUTE

:RUN_WITH_UI
call :INIT_UI
call :PRINT_BANNER
echo.
call :PRINT_OK "Starting project script..."
echo.

:RUN_EXECUTE
call "!PROJECT_SCRIPT!"
set "RC=!ERRORLEVEL!"

if "!QUIET!"=="1" goto RUN_FINISH
echo.
if !RC! equ 0 (
    call :PRINT_OK "Project !PROJECT_NAME! finished successfully."
) else (
    call :PRINT_ERR "Project !PROJECT_NAME! exited with code !RC!."
)
echo.

:RUN_FINISH
set "FINISH_RC=!RC!"
goto FINISH

:PROJECT_NOT_FOUND
if not "!QUIET!"=="1" (
    call :INIT_UI
    call :PRINT_HEADER
    echo.
    call :PRINT_ERR "Project !PROJECT_NAME! was not found."
    echo.
    call :PRINT_SECTION "Projects"
    call :LIST_PROJECTS
    call :PRINT_FOOTER "devstart --help - window stays open on error"
    exit /b !EXIT_NOT_FOUND!
)
call :PRINT_ERR "Project !PROJECT_NAME! was not found."
exit /b !EXIT_NOT_FOUND!

:SHOW_HELP
call :INIT_UI
call :RENDER_HELP
exit /b !EXIT_OK!

:LIST_ONLY
call :INIT_UI
call :PRINT_HEADER
echo.
call :ENSURE_PROJECTS_DIR
if errorlevel 1 exit /b !EXIT_ENV!
call :PRINT_SECTION "Projects"
call :LIST_PROJECTS
call :PRINT_FOOTER "devstart [project] to launch"
echo.
exit /b !EXIT_OK!

:SHOW_VERSION
call :INIT_UI
echo.
echo   %C_BOLD%devstart%C_RESET% %C_DIM%version %DEVSTART_VERSION%%C_RESET%
echo.
exit /b !EXIT_OK!

:FINISH
if not defined FINISH_RC set "FINISH_RC=1"
if !FINISH_RC! neq 0 (
    if not "!QUIET!"=="1" call :PRINT_FOOTER "Error - window stays open"
    exit /b !FINISH_RC!
)
if not "!AUTO_CLOSE!"=="1" exit /b !FINISH_RC!
if not "!QUIET!"=="1" call :PRINT_FOOTER "Window closes automatically - use --stay-open to keep it"
set "DS_HARD_EXIT=1"
exit /b !FINISH_RC!

:MATCH_ALIAS
for /f "usebackq eol=# tokens=1 delims= " %%L in ("%~1") do (
    if /i "%%L"=="!PROJECT_NAME!" (
        set "PROJECT_SCRIPT=%~2"
        exit /b 0
    )
)
exit /b 1

:COLLECT_ALIASES
setlocal EnableDelayedExpansion
set "OUT_VAR=%~2"
set "LIST="
for /f "usebackq eol=# delims=" %%L in ("%~1") do (
    set "LINE=%%L"
    if defined LINE (
        if defined LIST (set "LIST=!LIST!, !LINE!") else set "LIST=!LINE!"
    )
)
endlocal & set "%OUT_VAR%=%LIST%"
exit /b 0

:LIST_PROJECTS
dir /b "%PROJECTS_DIR%\*.bat" 2>nul | findstr /i "." >nul
if errorlevel 1 (
    echo   %C_DIM%^(no projects registered^)%C_RESET%
    exit /b 0
)
for %%F in ("%PROJECTS_DIR%\*.bat") do (
    set "ALIAS_HINT="
    if exist "%%~dpnF.aliases" call :COLLECT_ALIASES "%%~dpnF.aliases" ALIAS_HINT
    if defined ALIAS_HINT (
        echo   %C_GREEN%*%C_RESET%  %%~nF  %C_DIM%^(also: !ALIAS_HINT!^)%C_RESET%
    ) else (
        echo   %C_GREEN%*%C_RESET%  %%~nF
    )
)
exit /b 0

:ENSURE_PROJECTS_DIR
if exist "%PROJECTS_DIR%\" exit /b 0
call :PRINT_ERR "Projects directory not found:"
if not "%QUIET%"=="1" echo           "%PROJECTS_DIR%"
exit /b !EXIT_ENV!

:RESOLVE_PROJECT
set "PROJECT_SCRIPT="
for %%F in ("%PROJECTS_DIR%\*.bat") do (
    if /i "%%~nF"=="!PROJECT_NAME!" set "PROJECT_SCRIPT=%%~fF"
)
if defined PROJECT_SCRIPT exit /b 0
for %%A in ("%PROJECTS_DIR%\*.aliases") do (
    if exist "%%~dpnA.bat" call :MATCH_ALIAS "%%A" "%%~dpnA.bat"
)
if defined PROJECT_SCRIPT exit /b 0
exit /b !EXIT_NOT_FOUND!

:RENDER_HELP
call :PRINT_HEADER
echo.
call :PRINT_SECTION "Usage"
call :USAGE_ROW "devstart [project]"                 "Start by script name or alias"
call :USAGE_ROW "devstart --list"                    "List available projects"
call :USAGE_ROW "devstart --projects"                "Same as --list"
call :USAGE_ROW "devstart --quiet [project]"         "Minimal output for CI/scripts"
call :USAGE_ROW "devstart --stay-open [project]"    "Keep this window open after start"
call :USAGE_ROW "devstart --version"                 "Show version"
call :USAGE_ROW "devstart --help"                    "Show this help"
echo.
call :PRINT_SECTION "Environment"
echo   %C_DIM%DEVSTART_PROJECTS_DIR%C_RESET%    override projects folder
echo   %C_DIM%default%C_RESET%                   %PROJECTS_DIR%
echo.
call :ENSURE_PROJECTS_DIR
if errorlevel 1 exit /b 0
call :PRINT_SECTION "Projects"
call :LIST_PROJECTS
call :PRINT_FOOTER "devstart [project] to launch"
echo.
exit /b 0

:INIT_UI
if "%QUIET%"=="1" exit /b 0
chcp 65001 >nul 2>&1
for /F "delims=" %%A in ('echo prompt $E^| cmd') do set "ESC=%%A"
set "C_RESET=%ESC%[0m"
set "C_BOLD=%ESC%[1m"
set "C_DIM=%ESC%[2m"
set "C_CYAN=%ESC%[36m"
set "C_GREEN=%ESC%[32m"
set "C_YELLOW=%ESC%[33m"
set "C_RED=%ESC%[31m"
set "C_MAGENTA=%ESC%[35m"
set "C_WHITE=%ESC%[97m"
exit /b 0

:PRINT_HEADER
echo.
echo   %C_CYAN%+----------------------------------------------------------+%C_RESET%
call :BOX_ROW
call :BOX_ROW_TITLE
call :BOX_ROW_DIM "Local development environment launcher"
call :BOX_ROW
echo   %C_CYAN%+----------------------------------------------------------+%C_RESET%
exit /b 0

:BOX_ROW
setlocal EnableDelayedExpansion
set /a INNER=58
set "TXT=%~1"
if not defined TXT set "TXT="
call :STRLEN "!TXT!" LEN
set /a PAD=INNER-LEN
if !PAD! lss 0 set "PAD=0"
call :MAKE_SPACES PAD FILL
echo   %C_CYAN%^|%C_RESET%!TXT!!FILL!%C_CYAN%^|%C_RESET%
endlocal
exit /b 0

:BOX_ROW_TITLE
setlocal EnableDelayedExpansion
set /a INNER=58
set "V=%DEVSTART_VERSION%"
set "TITLE_PLAIN=   devstart  v!V!"
call :STRLEN "!TITLE_PLAIN!" VIS
set /a PAD=INNER-VIS
if !PAD! lss 0 set "PAD=0"
call :MAKE_SPACES PAD FILL
echo   %C_CYAN%^|%C_RESET%   %C_BOLD%%C_WHITE%devstart%C_RESET%  %C_DIM%v!V!%C_RESET%!FILL!%C_CYAN%^|%C_RESET%
endlocal
exit /b 0

:BOX_ROW_DIM
setlocal EnableDelayedExpansion
set /a INNER=58
set "TXT=%~1"
call :STRLEN "!TXT!" TLEN
set /a VIS=3+TLEN
set /a PAD=INNER-VIS
if !PAD! lss 0 set "PAD=0"
call :MAKE_SPACES PAD FILL
echo   %C_CYAN%^|%C_RESET%   %C_DIM%!TXT!%C_RESET%!FILL!%C_CYAN%^|%C_RESET%
endlocal
exit /b 0

:MAKE_SPACES
setlocal EnableDelayedExpansion
set /a N=%~1
set "OUT="
for /L %%I in (1,1,%N%) do set "OUT=!OUT! "
endlocal & set "%~2=%OUT%"
exit /b 0

:STRLEN
setlocal EnableDelayedExpansion
set "s=%~1"
set /a n=0
:STRLEN_LOOP
if not defined s goto STRLEN_DONE
set "s=!s:~1!"
set /a n+=1
goto STRLEN_LOOP
:STRLEN_DONE
endlocal & set "%~2=%n%"
exit /b 0

:PRINT_BANNER
call :PRINT_HEADER
echo.
echo   %C_DIM%project%C_RESET%   %C_BOLD%%C_CYAN%!PROJECT_NAME!%C_RESET%
echo   %C_DIM%script%C_RESET%    %C_DIM%!PROJECT_SCRIPT!%C_RESET%
exit /b 0

:PRINT_SECTION
echo   %C_MAGENTA%^>%C_RESET%  %C_BOLD%%~1%C_RESET%
echo   %C_DIM%----------------------------------------------------------------------------%C_RESET%
exit /b 0

:USAGE_ROW
setlocal EnableDelayedExpansion
set "CMD=%~1"
set "DESC=%~2"
set /a COL=34
call :STRLEN "!CMD!" CMD_LEN
set /a GAP=COL-CMD_LEN
if !GAP! lss 2 set "GAP=2"
call :MAKE_SPACES GAP PAD
echo   %C_CYAN%!CMD!%C_RESET%!PAD!%C_DIM%!DESC!%C_RESET%
endlocal
exit /b 0

:PRINT_FOOTER
echo   %C_DIM%----------------------------------------------------------------------------%C_RESET%
echo   %C_DIM%Tip:%C_RESET% %~1
exit /b 0

:PRINT_OK
if "%QUIET%"=="1" (
    echo [ok] %~1
    exit /b 0
)
echo   %C_GREEN%+%C_RESET%  %~1
exit /b 0

:PRINT_ERR
if "%QUIET%"=="1" (
    echo [error] %~1
    exit /b 0
)
echo   %C_RED%x%C_RESET%  %~1
exit /b 0

:PRINT_DIM
if "%QUIET%"=="1" (
    echo %~1
    exit /b 0
)
echo   %C_DIM%%~1%C_RESET%
exit /b 0
