@echo off
REM ============================================================
REM bootstrap.bat
REM
REM Single-file installer / updater / launcher for TrussLeafAssembly.
REM Send THIS file to the steel detailer. They double-click it:
REM
REM   First run:
REM     - Installs Git if missing (via winget) or links to download
REM     - Asks where to install (default ~\Projects\TrussLeafAssembly)
REM     - Clones the repo (PAT entered via Git Credential Manager
REM       when Git prompts for credentials -- send the PAT separately)
REM     - Saves the chosen path to %APPDATA%\TrussLeafAssembly\install-path.txt
REM     - Calls update.bat: prereqs + pull main + build (no launch)
REM     - Creates two Desktop shortcuts:
REM         "TrussLeafAssembly"        -> TrussMaui.exe (direct launch)
REM         "TrussLeafAssembly Update" -> repo\update.bat
REM
REM   Every run after:
REM     - Reads the saved path from the state file
REM     - Re-runs update.bat (pull + build) and refreshes the shortcuts
REM
REM The .bat can live anywhere -- on a network drive, the detailer's
REM Desktop, etc. After first run, daily use is via the Desktop shortcuts.
REM ============================================================
setlocal enabledelayedexpansion

REM ====== Azure DevOps repo URL (used only on first clone) ======
set "REPO_URL=https://dev.azure.com/BCSFAB/Bridge%%20Design%%20Automation/_git/TrussLeafAssembly"

REM ====== State file: remembers where the repo was cloned ======
set "STATE_DIR=%APPDATA%\TrussLeafAssembly"
set "STATE_FILE=%STATE_DIR%\install-path.txt"

echo.
echo =====================================================
echo   TrussLeafAssembly Bootstrap / Update
echo =====================================================

REM ============================================================
REM Step 1: locate the repo (state file -> auto-detect -> ask)
REM ============================================================
set "REPO_DIR="

REM (a) Saved state from a previous run
if exist "%STATE_FILE%" (
  set /p REPO_DIR=<"%STATE_FILE%"
  if exist "!REPO_DIR!\.git" (
    echo Using saved install: !REPO_DIR!
    goto :have_repo
  ) else (
    echo Saved path !REPO_DIR! no longer exists -- will prompt.
    set "REPO_DIR="
  )
)

REM (b) Running from inside the repo (file lives next to .git)
if exist "%~dp0\.git" if exist "%~dp0\TrussMaui\TrussMaui.csproj" (
  set "REPO_DIR=%~dp0"
  if "!REPO_DIR:~-1!"=="\" set "REPO_DIR=!REPO_DIR:~0,-1!"
  echo Running from inside repo: !REPO_DIR!
  goto :save_state
)

REM (c) First-time install -- ensure git, then clone

echo.
echo --- First-time setup ---
echo.
echo You'll need a Personal Access Token (PAT) from Azure DevOps.
echo The project maintainer should have sent it to you separately.
echo You'll be asked to paste it after Git is installed.
echo.
echo Tekla Structures is OPTIONAL. If you don't have Tekla installed,
echo the build will skip macro deployment ^(harmless warning^) and you
echo can still use the MAUI design app to configure and save bridges.
echo.
pause

REM Step 1c-i: ensure Git
where git >nul 2>&1
if not errorlevel 1 goto :git_ok

echo.
echo --- Installing Git ---
where winget >nul 2>&1
if errorlevel 1 goto :git_manual

winget install --id Git.Git -e --accept-source-agreements --accept-package-agreements
if errorlevel 1 goto :git_manual

REM winget update doesn't propagate PATH to this shell -- prepend the canonical install dir.
if exist "%ProgramFiles%\Git\cmd\git.exe" (
  set "PATH=%ProgramFiles%\Git\cmd;%PATH%"
  goto :git_ok
)

:git_manual
echo.
echo Could not auto-install Git. Please install it manually:
echo     https://git-scm.com/download/win
echo Use the default install options. After install, close this window
echo and re-run bootstrap.bat.
start "" "https://git-scm.com/download/win"
echo.
pause
exit /b 1

:git_ok

REM Step 1c-ii: ask install location
echo.
set "DEFAULT_DEST=%USERPROFILE%\Projects\TrussLeafAssembly"
set /p "REPO_DIR=Install path (Enter for default: %DEFAULT_DEST%): "
if "!REPO_DIR!"=="" set "REPO_DIR=%DEFAULT_DEST%"

REM Step 1c-iii: clone (skip if a clone already exists at that path)
if exist "!REPO_DIR!\.git" (
  echo Repo already exists at !REPO_DIR! -- will update instead of clone.
  goto :save_state
)

REM Make parent dir
for %%P in ("!REPO_DIR!") do set "PARENT=%%~dpP"
if not exist "!PARENT!" mkdir "!PARENT!" 2>nul

echo.
set /p "PAT=Paste your Azure DevOps PAT and press Enter: "
if "!PAT!"=="" (
  echo.
  echo ERROR: no PAT entered. Aborting.
  pause
  exit /b 1
)

REM Make Git Credential Manager use stored basic-auth creds for Azure DevOps
REM instead of its default OAuth/browser flow. Without this, a future pull may
REM ignore the PAT we seed below and try to pop a Microsoft sign-in window.
git config --global credential.https://dev.azure.com.provider generic >nul 2>&1

echo.
echo Cloning repository to !REPO_DIR!
echo.
git clone https://pat:!PAT!@dev.azure.com/BCSFAB/Bridge%%20Design%%20Automation/_git/TrussLeafAssembly "!REPO_DIR!"
if errorlevel 1 (
  echo.
  echo Clone failed. Common causes:
  echo   - Wrong / expired PAT
  echo   - PAT lacks 'Code (Read)' scope on this repo
  echo   - No network access to dev.azure.com
  echo.
  set "PAT="
  pause
  exit /b 1
)

REM Strip the PAT out of the remote URL so it's not sitting in .git/config,
REM then seed Windows Credential Manager (via Git Credential Manager) so
REM future pulls from update.bat work without re-prompting.
pushd "!REPO_DIR!"
git remote set-url origin "%REPO_URL%"
(
  echo protocol=https
  echo host=dev.azure.com
  echo username=pat
  echo password=!PAT!
  echo.
) | git credential approve
popd
set "PAT="

:save_state
REM Persist the install path so future runs skip the prompt.
if not exist "%STATE_DIR%" mkdir "%STATE_DIR%" 2>nul
> "%STATE_FILE%" echo !REPO_DIR!

:have_repo

REM ============================================================
REM Step 2: bring the existing clone up to date with origin/main.
REM
REM We always pull here -- not only when files are missing -- so
REM the clone is guaranteed to contain whatever tracked files the
REM newer bootstrap expects. This lets the maintainer ship a single
REM bootstrap.bat that "just works" on any prior clone, no matter
REM how old. update.bat itself also pulls, but we have to pull here
REM first to make sure update.bat actually exists.
REM ============================================================
cd /d "!REPO_DIR!"

echo.
echo --- Syncing to origin/main ---
git fetch origin
if errorlevel 1 goto :sync_fail

git checkout main
if errorlevel 1 (
  echo.
  echo ERROR: could not switch to 'main' branch. You probably have
  echo uncommitted changes. From a terminal, run:
  echo     cd /d "!REPO_DIR!"
  echo     git status
  echo and then either commit/stash them or contact the maintainer.
  pause
  exit /b 1
)

git pull --ff-only origin main
if errorlevel 1 goto :sync_fail

if not exist "!REPO_DIR!\update.bat" (
  echo.
  echo ERROR: update.bat not found in !REPO_DIR! even after pulling main.
  echo The clone looks broken. To recover, run these from a terminal:
  echo     rmdir /s /q "!REPO_DIR!"
  echo     del "%STATE_FILE%"
  echo Then double-click bootstrap.bat again for a clean install.
  pause
  exit /b 1
)

REM ============================================================
REM Step 3: hand off to update.bat (prereq checks + build).
REM update.bat will also do a git pull -- harmless no-op since
REM we just did one above.
REM ============================================================
call "!REPO_DIR!\update.bat"
if errorlevel 1 exit /b 1
goto :build_done

:sync_fail
echo.
echo ERROR: failed to sync with origin/main. Check your network and
echo Azure DevOps credentials.
pause
exit /b 1

:build_done

REM ============================================================
REM Step 4: create / refresh Desktop shortcuts
REM   - "TrussLeafAssembly"        -> TrussMaui.exe (direct launch)
REM   - "TrussLeafAssembly Update" -> repo\update.bat (pull + build)
REM Idempotent: re-running bootstrap.bat just rewrites the .lnk files.
REM ============================================================
echo.
echo --- Creating Desktop shortcuts ---

REM Locate the TrussMaui.exe under bin\Release (TFM/RID can change with .NET updates).
set "APP_EXE="
for /f "delims=" %%f in ('dir /b /s /a-d "!REPO_DIR!\TrussMaui\bin\Release\TrussMaui.exe" 2^>nul') do set "APP_EXE=%%f"

REM Resolve the user's REAL Desktop folder. On most modern Windows installs the
REM Desktop is redirected into OneDrive (%USERPROFILE%\OneDrive\Desktop), and
REM %USERPROFILE%\Desktop doesn't even exist. Asking the shell directly via
REM [Environment]::GetFolderPath('Desktop') honors OneDrive, group-policy
REM redirection, and any other rebinding the user might have.
set "DESKTOP="
for /f "usebackq delims=" %%d in (`powershell -NoProfile -Command "[Environment]::GetFolderPath('Desktop')"`) do set "DESKTOP=%%d"
if "!DESKTOP!"=="" set "DESKTOP=%USERPROFILE%\Desktop"
echo   Desktop folder: !DESKTOP!

if defined APP_EXE (
  powershell -NoProfile -ExecutionPolicy Bypass -Command ^
    "$ErrorActionPreference='Stop';" ^
    "$s=(New-Object -ComObject WScript.Shell).CreateShortcut([IO.Path]::Combine($env:DESKTOP, 'TrussLeafAssembly.lnk'));" ^
    "$s.TargetPath=$env:APP_EXE;" ^
    "$s.WorkingDirectory=$env:REPO_DIR;" ^
    "$s.IconLocation=$env:APP_EXE + ',0';" ^
    "$s.Description='Launch the TrussLeafAssembly desktop app';" ^
    "$s.Save()"
  if errorlevel 1 (
    echo   ERROR: failed to create TrussLeafAssembly.lnk -- see message above.
  ) else (
    echo   Created: !DESKTOP!\TrussLeafAssembly.lnk
  )
) else (
  echo   WARNING: TrussMaui.exe not found -- skipping App shortcut.
  echo   ^(Did the build succeed? Check the output above.^)
)

set "UPDATE_BAT=!REPO_DIR!\update.bat"
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
  "$ErrorActionPreference='Stop';" ^
  "$s=(New-Object -ComObject WScript.Shell).CreateShortcut([IO.Path]::Combine($env:DESKTOP, 'TrussLeafAssembly Update.lnk'));" ^
  "$s.TargetPath=$env:UPDATE_BAT;" ^
  "$s.WorkingDirectory=$env:REPO_DIR;" ^
  "$s.Description='Pull the latest TrussLeafAssembly main branch and rebuild';" ^
  "$s.Save()"
if errorlevel 1 (
  echo   ERROR: failed to create TrussLeafAssembly Update.lnk -- see message above.
) else (
  echo   Created: !DESKTOP!\TrussLeafAssembly Update.lnk
)

echo.
echo =====================================================
echo   Done. Use the Desktop shortcuts going forward:
echo     TrussLeafAssembly        - launch the app
echo     TrussLeafAssembly Update - pull + build (no launch)
echo =====================================================
echo.
pause
exit /b 0
