@echo off
REM check-bios.cmd - Check and apply Dell BIOS update from WinPE x64
REM Called from startnet.cmd before imaging menu
REM Requires: Flash64W.exe (Dell 64-Bit BIOS Flash Utility) in same directory
REM
REM Exit behavior:
REM   - BIOS update applied  -> reboots automatically (flashes during POST)
REM   - Already up to date   -> returns to startnet.cmd
REM   - No match / no files  -> returns to startnet.cmd

set BIOSDIR=%~dp0
set FLASH=%BIOSDIR%Flash64W.exe
set MANIFEST=%BIOSDIR%models.txt

if not exist "%FLASH%" (
    echo   Flash64W.exe not found, skipping BIOS check.
    exit /b 0
)

if not exist "%MANIFEST%" (
    echo   models.txt not found, skipping BIOS check.
    exit /b 0
)

REM --- Get system model from WMI ---
set SYSMODEL=
for /f "skip=1 tokens=*" %%M in ('wmic csproduct get name 2^>NUL') do (
    if not defined SYSMODEL set "SYSMODEL=%%M"
)
REM Trim trailing whitespace
for /f "tokens=*" %%a in ("%SYSMODEL%") do set "SYSMODEL=%%a"

if "%SYSMODEL%"=="" (
    echo   Could not detect system model, skipping BIOS check.
    exit /b 0
)

echo   Model: %SYSMODEL%

REM --- Get current BIOS version ---
set BIOSVER=
for /f "skip=1 tokens=*" %%V in ('wmic bios get smbiosbiosversion 2^>NUL') do (
    if not defined BIOSVER set "BIOSVER=%%V"
)
for /f "tokens=*" %%a in ("%BIOSVER%") do set "BIOSVER=%%a"
echo   Current BIOS: %BIOSVER%

REM --- Read manifest and find matching BIOS file ---
REM Format: ModelSubstring|BIOSFile|Version
set BIOSFILE=
set TARGETVER=
for /f "usebackq eol=# tokens=1,2,3 delims=|" %%A in ("%MANIFEST%") do (
    echo "%SYSMODEL%" | find /I "%%A" >NUL
    if not errorlevel 1 (
        set "BIOSFILE=%%B"
        set "TARGETVER=%%C"
        goto :found_bios
    )
)

echo   No BIOS update available for this model.
exit /b 0

:found_bios
if not exist "%BIOSDIR%%BIOSFILE%" (
    echo   WARNING: %BIOSFILE% not found in BIOS folder.
    exit /b 0
)

REM --- Skip if already at target version ---
echo.%BIOSVER%| find /I "%TARGETVER%" >NUL
if not errorlevel 1 goto :already_current

REM --- Compare versions to prevent downgrade ---
REM Split current and target into major.minor.patch and compare numerically
call :compare_versions "%BIOSVER%" "%TARGETVER%"
if "%VERCMP%"=="newer" goto :already_newer
goto :do_flash

:already_current
echo   BIOS is already up to date - %TARGETVER%
exit /b 0

:already_newer
echo   Current BIOS %BIOSVER% is newer than target %TARGETVER% - skipping.
exit /b 0

:do_flash

echo   Update: %BIOSVER% -^> %TARGETVER%
echo   Applying BIOS update (this may take a few minutes, do not power off)...

REM --- Run Flash64W.exe from BIOS directory to avoid UNC path issues ---
REM Exit codes: 0=success, 2=reboot needed, 3=already current, 6=reboot needed
pushd "%BIOSDIR%"
Flash64W.exe /b="%BIOSFILE%" /s /f /l=X:\bios-update.log
set FLASHRC=%ERRORLEVEL%
popd
echo   Flash complete (exit code %FLASHRC%).

if "%FLASHRC%"=="3" (
    echo   BIOS is already up to date.
    exit /b 0
)

if "%FLASHRC%"=="0" (
    echo   BIOS update complete.
    exit /b 0
)

if "%FLASHRC%"=="2" goto :staged
if "%FLASHRC%"=="6" goto :staged

echo   WARNING: Flash64W.exe returned unexpected code %FLASHRC%.
echo   Check X:\bios-update.log for details.
exit /b 0

:staged
echo.
echo   ========================================
echo     BIOS update staged successfully.
echo     It will flash during POST after the
echo     post-imaging reboot.
echo   ========================================
echo.
exit /b 0

REM ============================================================
REM compare_versions - Compare two dotted version strings
REM   Usage: call :compare_versions "current" "target"
REM   Sets VERCMP=newer if current > target, older if current < target, equal if same
REM ============================================================
:compare_versions
set "VERCMP=equal"
set "_CV=%~1"
set "_TV=%~2"

REM Parse current version parts
for /f "tokens=1,2,3 delims=." %%a in ("%_CV%") do (
    set /a "C1=%%a" 2>NUL
    set /a "C2=%%b" 2>NUL
    set /a "C3=%%c" 2>NUL
)
REM Parse target version parts
for /f "tokens=1,2,3 delims=." %%a in ("%_TV%") do (
    set /a "T1=%%a" 2>NUL
    set /a "T2=%%b" 2>NUL
    set /a "T3=%%c" 2>NUL
)

if %C1% GTR %T1% ( set "VERCMP=newer" & goto :eof )
if %C1% LSS %T1% ( set "VERCMP=older" & goto :eof )
if %C2% GTR %T2% ( set "VERCMP=newer" & goto :eof )
if %C2% LSS %T2% ( set "VERCMP=older" & goto :eof )
if %C3% GTR %T3% ( set "VERCMP=newer" & goto :eof )
if %C3% LSS %T3% ( set "VERCMP=older" & goto :eof )
set "VERCMP=equal"
goto :eof
