@echo off
setlocal EnableExtensions EnableDelayedExpansion

REM ------------------------------------------------------------
REM 7 Days To Die - Mod Switcher (Vanilla / Modded / The Wasteland)
REM - Works from ANY location
REM - Remembers game path in C:\7d2d\gamepath.txt
REM - Stores zips in C:\7d2d
REM - Offers to download zips from your HTTPS if missing
REM - One-time backup Mods -> mods_vanilla
REM Relaunch in a persistent window (no parenthesis blocks)
REM ------------------------------------------------------------
set "VER=v2026-02-02.43"

REM --- Relaunch into a persistent window so it never flash-closes
if /I "%~1"=="--child" goto MAIN
start "7DTD Mod Switcher %VER%" cmd /k ""%~f0" --child"
exit /b

:MAIN
title 7DTD Mod Switcher %VER%
color 0A

set "ZIPROOT=C:\7d2d"
set "BACKUPROOT=%ZIPROOT%\backups"
set "VANILLABASE=%BACKUPROOT%\Mods_vanilla_baseline"
set "EXTRACTROOT=%ZIPROOT%\_extract"
set "EXTRACTWORK=%EXTRACTROOT%\work"
set "LOG=%ZIPROOT%\modswitcher.log"
set "SAVEDPATH=%ZIPROOT%\gamepath.txt"

set "ZIP_MODDED=%ZIPROOT%\7d2dmodded.zip"
set "ZIP_WASTE=%ZIPROOT%\thewasteland.zip"

set "URL_MODDED_1=https://suddenimpact.theworkpc.com/mods/7d2dModded.zip"
set "URL_MODDED_2=https://suddenimpact.theworkpc.com/mods/7d2dmodded.zip"
set "URL_WASTE=https://suddenimpact.theworkpc.com/mods/thewasteland.zip"

REM Default Steam paths (the (x86) one is the troublemaker if used incorrectly)
set "DEFAULT1=C:\Program Files (x86)\Steam\steamapps\common\7 Days To Die"
set "DEFAULT2=C:\Program Files\Steam\steamapps\common\7 Days To Die"

call :EnsureFolder "%ZIPROOT%" || goto FAIL
call :EnsureFolder "%BACKUPROOT%" || goto FAIL
call :EnsureFolder "%EXTRACTROOT%" || goto FAIL

call :Log "============================================================"
call :Log "Starting %VER%"
call :Log "ZIPROOT=%ZIPROOT%"
call :Log "============================================================"

cls
echo ============================================================
echo  7 Days To Die - Mod Switcher   %VER%
echo ============================================================
echo  Zips folder   : %ZIPROOT%
echo  Backups folder: %BACKUPROOT%
echo  Vanilla base  : %VANILLABASE%
echo  Log file      : %LOG%
echo ============================================================
echo.

REM --- Admin check (recommended)
net session >nul 2>&1
if not "%errorlevel%"=="0" (
  echo NOTE: Not running as Administrator.
  echo This may cause Access Denied in Program Files.
  echo.
  choice /c YN /n /m "Continue anyway? (Y/N): "
  if errorlevel 2 goto FAIL
)

where powershell >nul 2>&1 || (echo ERROR: powershell not found& goto FAIL)
where robocopy >nul 2>&1 || (echo ERROR: robocopy not found& goto FAIL)

REM ============================================================
REM Find game folder
REM ============================================================
set "GAMEDIR="

REM 1) Load saved path if valid
if exist "%SAVEDPATH%" (
  for /f "usebackq delims=" %%A in ("%SAVEDPATH%") do set "GAMEDIR=%%A"
  if not exist "!GAMEDIR!\7DaysToDie.exe" set "GAMEDIR="
)

REM 2) Ask about default location and check both defaults SAFELY
if not defined GAMEDIR (
  echo Did you install 7 Days To Die using Steam's default location? (Y/N)
  echo Default paths checked:
  echo   1) %DEFAULT1%
  echo   2) %DEFAULT2%
  choice /c YN /n /m "Your answer (Y/N): "
  if errorlevel 2 goto ASK_MANUAL

  REM IMPORTANT: Use delayed expansion inside any logic so (x86) won't break parsing
  if exist "!DEFAULT1!\7DaysToDie.exe" set "GAMEDIR=!DEFAULT1!"
  if not defined GAMEDIR if exist "!DEFAULT2!\7DaysToDie.exe" set "GAMEDIR=!DEFAULT2!"
)

:ASK_MANUAL
if not defined GAMEDIR (
  echo.
  echo Please paste your 7 Days To Die install folder path.
  echo Example: D:\SteamLibrary\steamapps\common\7 Days To Die
  set /p "MANPATH=Path: "
  if exist "!MANPATH!\7DaysToDie.exe" set "GAMEDIR=!MANPATH!"
)

if not defined GAMEDIR (
  echo.
  echo ERROR: Could not locate 7DaysToDie.exe.
  call :Log "ERROR: Could not locate 7DaysToDie.exe"
  goto FAIL
)

( echo !GAMEDIR! )>"%SAVEDPATH%"
set "MODSDIR=!GAMEDIR!\Mods"

echo.
echo Game folder:
echo   !GAMEDIR!
echo.

REM ============================================================
REM Vanilla baseline prompt (only if missing)
REM ============================================================
if not exist "%VANILLABASE%\" (
  echo ------------------------------------------------------------
  echo Vanilla baseline is NOT set.
  echo Option 1 restores from vanilla baseline.
  echo ------------------------------------------------------------
  choice /c YN /n /m "Capture Vanilla baseline now? (Y/N): "
  if errorlevel 2 goto MENU
  call :CaptureVanilla || goto FAIL
)

REM ============================================================
REM Menu
REM ============================================================
:MENU
echo.
echo ============================================================
echo   1 = Load VANILLA
echo   2 = Load MODDED
echo   3 = Load WASTELAND
echo   4 = Save current Mods as VANILLA baseline
echo   5 = Exit
echo ============================================================
set /p "OPT=Choose 1-5: "

if "%OPT%"=="1" goto DO_VANILLA
if "%OPT%"=="2" goto DO_MODDED
if "%OPT%"=="3" goto DO_WASTE
if "%OPT%"=="4" goto DO_CAPTURE
if "%OPT%"=="5" goto DONE
goto MENU

:DO_CAPTURE
call :CaptureVanilla || goto FAIL
echo Done.
goto MENU

:DO_VANILLA
if not exist "%VANILLABASE%\" (
  echo ERROR: Vanilla baseline missing: %VANILLABASE%
  goto FAIL
)
call :ResetMods || goto FAIL
call :Mirror "%VANILLABASE%" "!MODSDIR!" || goto FAIL
goto SUCCESS

:DO_MODDED
call :EnsureZip "%ZIP_MODDED%" "%URL_MODDED_1%" "%URL_MODDED_2%" || goto FAIL
echo.
echo Downloading and installing mods.
echo This can take several minutes. Please wait...
echo.
call :ResetMods || goto FAIL
call :InstallZip "%ZIP_MODDED%" || goto FAIL
goto SUCCESS

:DO_WASTE
call :EnsureZip "%ZIP_WASTE%" "%URL_WASTE%" "" || goto FAIL
echo.
echo Downloading and installing mods.
echo This can take several minutes. Please wait...
echo.
call :ResetMods || goto FAIL
call :InstallZip "%ZIP_WASTE%" || goto FAIL
goto SUCCESS

REM ============================================================
REM Functions
REM ============================================================

:CaptureVanilla
call :EnsureFolder "%VANILLABASE%" || exit /b 1
if not exist "!MODSDIR!\" call :EnsureFolder "!MODSDIR!" || exit /b 1
call :Mirror "!MODSDIR!" "%VANILLABASE%" || exit /b 1
echo Vanilla baseline saved to: %VANILLABASE%
call :Log "Captured vanilla baseline to %VANILLABASE%"
exit /b 0

:ResetMods
REM Timestamp
for /f "tokens=1-3 delims=/: " %%a in ("%date%") do set "D=%%c%%a%%b"
for /f "tokens=1-3 delims=:. " %%a in ("%time%") do set "T=%%a%%b%%c"
set "T=%T: =0%"
set "STAMP=%D%_%T%"

REM Backup current Mods if it exists
if exist "!MODSDIR!\" (
  set "BKP=%BACKUPROOT%\Mods_backup_%STAMP%"
  call :EnsureFolder "!BKP!" || exit /b 1
  call :Mirror "!MODSDIR!" "!BKP!" || exit /b 1

  pushd "!GAMEDIR!" >nul || exit /b 1
  ren "Mods" "Mods_prev_%STAMP%" >nul 2>&1
  popd >nul
)

call :EnsureFolder "!MODSDIR!" || exit /b 1
exit /b 0

:InstallZip
set "ZIPFILE=%~1"

if exist "%EXTRACTWORK%\" rmdir /s /q "%EXTRACTWORK%" >nul 2>&1
call :EnsureFolder "%EXTRACTWORK%" || exit /b 1

powershell -NoProfile -ExecutionPolicy Bypass -Command ^
  "Expand-Archive -LiteralPath '%ZIPFILE%' -DestinationPath '%EXTRACTWORK%' -Force" ^
  >> "%LOG%" 2>&1

if not "%errorlevel%"=="0" (
  echo ERROR: Failed to extract zip.
  call :Log "ERROR: Expand-Archive failed for %ZIPFILE%"
  exit /b 1
)

if exist "%EXTRACTWORK%\Mods\" (
  call :Mirror "%EXTRACTWORK%\Mods" "!MODSDIR!" || exit /b 1
) else (
  call :Mirror "%EXTRACTWORK%" "!MODSDIR!" || exit /b 1
)

rmdir /s /q "%EXTRACTWORK%" >nul 2>&1
exit /b 0

:EnsureZip
set "OUT=%~1"
set "U1=%~2"
set "U2=%~3"

if exist "%OUT%" exit /b 0

echo.
echo %~nx1 is missing from %ZIPROOT%.
choice /c YN /n /m "Download it now? (Y/N): "
if errorlevel 2 exit /b 1

call :Log "Downloading %OUT% from %U1%"
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
  "try { Invoke-WebRequest -Uri '%U1%' -OutFile '%OUT%' -UseBasicParsing } catch { exit 2 }" ^
  >> "%LOG%" 2>&1

if exist "%OUT%" exit /b 0

if not "%U2%"=="" (
  call :Log "URL1 failed; trying URL2=%U2%"
  powershell -NoProfile -ExecutionPolicy Bypass -Command ^
    "try { Invoke-WebRequest -Uri '%U2%' -OutFile '%OUT%' -UseBasicParsing } catch { exit 2 }" ^
    >> "%LOG%" 2>&1
)

if exist "%OUT%" exit /b 0
echo ERROR: Download failed. Check log: %LOG%
exit /b 1

:Mirror
set "SRC=%~1"
set "DST=%~2"
call :EnsureFolder "%DST%" >nul 2>&1
robocopy "%SRC%" "%DST%" /MIR /R:2 /W:1 /NFL /NDL /NP /NJH /NJS >> "%LOG%" 2>&1
if %errorlevel% GEQ 8 exit /b 1
exit /b 0

:EnsureFolder
set "F=%~1"
if exist "%F%\" exit /b 0
if exist "%F%" del /f /q "%F%" >nul 2>&1
mkdir "%F%" >nul 2>&1
if exist "%F%\" exit /b 0
exit /b 1

:Log
>> "%LOG%" echo [%date% %time%] %*
exit /b 0

REM ============================================================
REM End states
REM ============================================================

:SUCCESS
echo.
echo ============================================================
echo COMPLETED SUCCESSFULLY.
echo Press any key to exit...
echo ============================================================
pause >nul
exit /b 0

:FAIL
echo.
echo ============================================================
echo Fuck. No bueno. Something failed.
echo Check the log: %LOG%
echo Press any key to exit...
echo ============================================================
pause >nul
exit /b 1

:DONE
echo.
echo ============================================================
echo Goodbye.
echo You can now close this page...
echo ============================================================
pause >nul
exit /b 0
