@echo off
setlocal enabledelayedexpansion

:: %~dp0 is this script's own folder (repo root), trailing backslash included —
:: resolves correctly regardless of which drive/path the repo is cloned to.
set "REPOROOT=%~dp0"

:: ============================================================
::  STEP 1 - Select which components to build
:: ============================================================
cls
echo ================================================================
echo                    GB5  LOCAL  BUILD  UTILITY
echo ================================================================
echo.
echo   [1] PlatformHost
echo       Modules : DevAdmin, SqlWorkbench, Automation, PIE, FLS,
echo                 Compliance, Partner, KMS, TCMS, IceImport, Entitlement
echo.
echo   [2] BusinessHost
echo       Modules : CRM, Analytics, Marketing, Admin, MM, Logistics,
echo                 Maintenance, Vehicle, QMS, FM, DXP
echo.
echo   [3] EngagementHost
echo       Modules : CollabSpace, Enablement, AMP, WorkInstruction,
echo                 FBCK, CMS, DMS, PERM, CompetencyMgmt,
echo                 ECP ^(Communication/Correspondence/Collaboration/Meeting^)
echo.
echo   [4] HRFinanceHost
echo       Modules : PayRoll, Recruitment, SkillManagement, TMS,
echo                 Accounts, Costing, FAM, PAY
echo.
echo   [5] FrameworkSL     ^(gb5.service - gateway alias: /fws/^)
echo.
echo   [6] GB5Build        ^(API Gateway / YARP reverse proxy^)
echo.
echo   [7] ALL
echo.
echo ================================================================
set /p SEL="Enter the numbers to build, space-separated (e.g. 1 4), or 7 for ALL: "

if "%SEL%"=="" (
    echo.
    echo No selection made. Exiting.
    cmd /k echo Closed with no build performed. You can close this window now.
    exit /b 1
)

set DO_PlatformHost=0
set DO_BusinessHost=0
set DO_EngagementHost=0
set DO_HRFinanceHost=0
set DO_FrameworkSL=0
set DO_GB5Build=0

for %%N in (%SEL%) do (
    if "%%N"=="1" set DO_PlatformHost=1
    if "%%N"=="2" set DO_BusinessHost=1
    if "%%N"=="3" set DO_EngagementHost=1
    if "%%N"=="4" set DO_HRFinanceHost=1
    if "%%N"=="5" set DO_FrameworkSL=1
    if "%%N"=="6" set DO_GB5Build=1
    if "%%N"=="7" (
        set DO_PlatformHost=1
        set DO_BusinessHost=1
        set DO_EngagementHost=1
        set DO_HRFinanceHost=1
        set DO_FrameworkSL=1
        set DO_GB5Build=1
    )
)

set "HOSTLIST="
if %DO_PlatformHost%==1   set "HOSTLIST=!HOSTLIST! PlatformHost"
if %DO_BusinessHost%==1   set "HOSTLIST=!HOSTLIST! BusinessHost"
if %DO_EngagementHost%==1 set "HOSTLIST=!HOSTLIST! EngagementHost"
if %DO_HRFinanceHost%==1  set "HOSTLIST=!HOSTLIST! HRFinanceHost"
if %DO_FrameworkSL%==1    set "HOSTLIST=!HOSTLIST! FrameworkSL"
if %DO_GB5Build%==1       set "HOSTLIST=!HOSTLIST! GB5Build"

if "!HOSTLIST!"=="" (
    echo.
    echo Invalid selection - nothing to build.
    cmd /k echo Closed with no build performed. You can close this window now.
    exit /b 1
)

echo.
echo Selected:!HOSTLIST!
echo.

:: ============================================================
::  STEP 2 - Portable build (runs on both Windows and Linux)
::  No -r/RID is passed to dotnet publish, so:
::    - PublishReadyToRun (Directory.Build.props) auto-disables,
::      since it's conditioned on RuntimeIdentifier being set.
::    - The output is framework-dependent IL that runs on either
::      OS via `dotnet <Host>.dll`, as long as the target machine
::      has the matching .NET runtime installed.
::  Trade-off: no ReadyToRun native precompilation, so cold start
::  is slower than the old per-OS builds. Native/OS-specific
::  runtime assets (e.g. Microsoft.Data.SqlClient's SNI library)
::  are still bundled for both OSes and selected at run time.
:: ============================================================
set "OUT=C:\GB5BuildFile\portable"
set "LOGDIR=%OUT%\_logs"
echo.
echo Target: portable build (no RID) - runs on Windows and Linux
echo.

:: ============================================================
::  STEP 3 - Ensure the output folder exists (never wipe it)
:: ============================================================
if not exist "%OUT%" (
    echo Creating %OUT% ...
    mkdir "%OUT%"
) else (
    echo %OUT% already exists - leaving its existing contents in place.
)
if not exist "%LOGDIR%" mkdir "%LOGDIR%"
echo.

:: ============================================================
::  STEP 4 - Build (dotnet publish) the selected components
::  Errors are captured to a full-detail log file per component
::  (MSBuild's terminal logger otherwise collapses failures down
::  to just an error COUNT, hiding the actual "file(line): error"
::  text). On failure we grep the log and print the real errors.
:: ============================================================
if %DO_PlatformHost%==1 (
    echo === Building PlatformHost ^(portable^) ===
    set "LOGFILE=%LOGDIR%\PlatformHost_build.log"
    if exist "!LOGFILE!" del "!LOGFILE!"
    dotnet publish "%REPOROOT%GB5Solution\Hosts\Platform\PlatformHost\PlatformHost.csproj" -c Release -o "%OUT%\PlatformHost" -tl:off -v:quiet -flp:logfile="!LOGFILE!";verbosity=normal
    if errorlevel 1 call :showerrors "!LOGFILE!" "PlatformHost" & goto :error
)

if %DO_BusinessHost%==1 (
    echo === Building BusinessHost ^(portable^) ===
    set "LOGFILE=%LOGDIR%\BusinessHost_build.log"
    if exist "!LOGFILE!" del "!LOGFILE!"
    dotnet publish "%REPOROOT%GB5Solution\Hosts\Business\BusinessHost\BusinessHost.csproj" -c Release -o "%OUT%\BusinessHost" -tl:off -v:quiet -flp:logfile="!LOGFILE!";verbosity=normal
    if errorlevel 1 call :showerrors "!LOGFILE!" "BusinessHost" & goto :error
)

if %DO_EngagementHost%==1 (
    echo === Building EngagementHost ^(portable^) ===
    set "LOGFILE=%LOGDIR%\EngagementHost_build.log"
    if exist "!LOGFILE!" del "!LOGFILE!"
    dotnet publish "%REPOROOT%GB5Solution\Hosts\Engagement\EngagementHost\EngagementHost.csproj" -c Release -o "%OUT%\EngagementHost" -tl:off -v:quiet -flp:logfile="!LOGFILE!";verbosity=normal
    if errorlevel 1 call :showerrors "!LOGFILE!" "EngagementHost" & goto :error
)

if %DO_HRFinanceHost%==1 (
    echo === Building HRFinanceHost ^(portable^) ===
    set "LOGFILE=%LOGDIR%\HRFinanceHost_build.log"
    if exist "!LOGFILE!" del "!LOGFILE!"
    dotnet publish "%REPOROOT%GB5Solution\Hosts\HRFinance\HRFinanceHost\HRFinanceHost.csproj" -c Release -o "%OUT%\HRFinanceHost" -tl:off -v:quiet -flp:logfile="!LOGFILE!";verbosity=normal
    if errorlevel 1 call :showerrors "!LOGFILE!" "HRFinanceHost" & goto :error
)

if %DO_FrameworkSL%==1 (
    echo === Building FrameworkSL ^(portable^) ===
    set "LOGFILE=%LOGDIR%\FrameworkSL_build.log"
    if exist "!LOGFILE!" del "!LOGFILE!"
    dotnet publish "%REPOROOT%GB5Framework\FrameworkSL\FrameworkSL.csproj" -c Release -o "%OUT%\FrameworkSL" -tl:off -v:quiet -flp:logfile="!LOGFILE!";verbosity=normal
    if errorlevel 1 call :showerrors "!LOGFILE!" "FrameworkSL" & goto :error
    REM Safety net: Logs\** should already be excluded in the csproj, but wipe it anyway if it reappears
    if exist "%OUT%\FrameworkSL\Logs" rmdir /s /q "%OUT%\FrameworkSL\Logs"
)

if %DO_GB5Build%==1 (
    echo === Building GB5Build ^(portable^) ===
    set "LOGFILE=%LOGDIR%\GB5Build_build.log"
    if exist "!LOGFILE!" del "!LOGFILE!"
    dotnet publish "%REPOROOT%GB5Solution\GB5Build\GB5Build\GB5Build.csproj" -c Release -o "%OUT%\GB5Build" -tl:off -v:quiet -flp:logfile="!LOGFILE!";verbosity=normal
    if errorlevel 1 call :showerrors "!LOGFILE!" "GB5Build" & goto :error
)

echo.
echo ================================================================
echo   BUILD COMPLETE for:!HOSTLIST!
echo   Target: portable ^(Windows + Linux, needs .NET 10 runtime^)
echo   Output location: %OUT%
echo   Build logs: %LOGDIR%
echo ================================================================
echo.
echo   To run on Windows: dotnet ^<Host^>.dll  (or the generated .exe)
echo   To run on Linux:   dotnet ^<Host^>.dll
echo.

:: ============================================================
::  STEP 5 - Ask output format
:: ============================================================
:ask_format
echo   [1] Keep as normal folder structure
echo   [2] Also package as zip file^(s^)
echo.
set /p FORMAT="Enter choice (1 or 2): "

if "%FORMAT%"=="1" goto :done
if "%FORMAT%"=="2" goto :make_zip
echo Invalid choice, please enter 1 or 2.
goto :ask_format

:make_zip
echo.
echo === Packaging into zip file(s) ===
for %%H in (!HOSTLIST!) do (
    echo   - %%H.zip
    tar -a -cf "%OUT%\%%H.zip" -C "%OUT%\%%H" .
)
echo.
echo ================================================================
echo   ZIP PACKAGE COMPLETE
echo ================================================================
for %%H in (!HOSTLIST!) do (
    echo     %OUT%\%%H.zip
)
goto :done

:done
echo.
echo ================================================================
echo   ALL DONE - files are in %OUT%
echo ================================================================
cmd /k echo Finished. Close this window whenever you're ready.
exit /b 0

:showerrors
:: %1 = log file path, %2 = component name
echo.
echo ================================================================
echo   *** BUILD ERRORS in %~2 ***
echo ================================================================
findstr /I /C:": error" "%~1"
if errorlevel 1 (
    echo   ^(No "error" lines matched in the log - dumping last 40 lines instead:^)
    echo.
    powershell -NoProfile -Command "Get-Content -Path '%~1' -Tail 40"
)
echo.
echo   Full detailed log saved at: %~1
echo ================================================================
goto :eof

:error
echo.
echo ================================================================
echo   *** BUILD FAILED ***
echo   See the error text printed above, or open the log file listed
echo   above for full detail (every warning/error, in build order).
echo ================================================================
cmd /k echo Build failed. Close this window whenever you're ready.
exit /b 1
