@echo off
REM Copyright 2024 The Hush Developers
REM Copyright 2024 The DragonX Developers
REM Released under the GPLv3
REM
REM Download and apply a DRAGONX blockchain bootstrap on Windows.
REM Safely preserves wallet.dat and configuration files.

setlocal enabledelayedexpansion

set "BOOTSTRAP_BASE_URL=https://bootstrap.dragonx.is"
set "BOOTSTRAP_FALLBACK_URL=https://bootstrap2.dragonx.is"
set "BOOTSTRAP_FILE=DRAGONX.zip"
set "CHAIN_NAME=DRAGONX"

REM Data directory on Windows
set "DATADIR=%APPDATA%\Hush\%CHAIN_NAME%"

REM Find dragonx-cli relative to this script
set "CLI="
set "SCRIPT_DIR=%~dp0"
if exist "%SCRIPT_DIR%dragonx-cli.exe" (
    set "CLI=%SCRIPT_DIR%dragonx-cli.exe"
)

echo ============================================
echo   DragonX Bootstrap Installer
echo ============================================
echo.
echo [INFO] Data directory: %DATADIR%
echo.

REM Step 1: Stop daemon if running
call :stop_daemon
if errorlevel 1 goto :error_exit

REM Step 2: Clean old chain data
call :clean_chain_data
if errorlevel 1 goto :error_exit

REM Step 3: Download bootstrap
call :download_bootstrap
if errorlevel 1 goto :error_exit

REM Step 4: Extract bootstrap
call :extract_bootstrap
if errorlevel 1 goto :error_exit

echo.
echo [INFO] Bootstrap installation complete!
echo [INFO] You can now start DragonX with: dragonxd.exe
echo.
goto :EOF

REM ============================================
REM  Stop daemon if running
REM ============================================
:stop_daemon
if "%CLI%"=="" (
    echo [WARN] dragonx-cli.exe not found next to this script.
    echo [WARN] Please make sure the DragonX daemon is stopped before continuing.
    set /p "ANSWER=Is the DragonX daemon stopped? (y/N): "
    if /i not "!ANSWER!"=="y" (
        echo [ERROR] Please stop the daemon first and run this script again.
        exit /b 1
    )
    exit /b 0
)

"%CLI%" getinfo >nul 2>&1
if errorlevel 1 (
    echo [INFO] Daemon is not running.
    exit /b 0
)

echo [INFO] Stopping DragonX daemon...
"%CLI%" stop >nul 2>&1

set "TRIES=0"
:wait_loop
"%CLI%" getinfo >nul 2>&1
if errorlevel 1 goto :daemon_stopped
timeout /t 2 /nobreak >nul
set /a TRIES+=1
if %TRIES% geq 60 (
    echo [ERROR] Daemon did not stop after 120 seconds. Please stop it manually and retry.
    exit /b 1
)
goto :wait_loop

:daemon_stopped
echo [INFO] Daemon stopped.
exit /b 0

REM ============================================
REM  Clean blockchain data, preserving wallet and config
REM ============================================
:clean_chain_data
if not exist "%DATADIR%" (
    echo [INFO] Data directory does not exist yet, creating it.
    mkdir "%DATADIR%"
    exit /b 0
)

echo [INFO] Cleaning blockchain data from %DATADIR% ...

REM Preserve wallet.dat and config
set "TMPDIR=%TEMP%\dragonx-bootstrap-%RANDOM%"
mkdir "%TMPDIR%" 2>nul

for %%F in (wallet.dat DRAGONX.conf peers.dat) do (
    if exist "%DATADIR%\%%F" (
        copy /y "%DATADIR%\%%F" "%TMPDIR%\%%F" >nul
    )
)

REM Remove blockchain directories and files
for %%D in (blocks chainstate notarizations komodo) do (
    if exist "%DATADIR%\%%D" (
        rmdir /s /q "%DATADIR%\%%D" 2>nul
    )
)
for %%F in (db.log debug.log fee_estimates.dat banlist.dat) do (
    if exist "%DATADIR%\%%F" (
        del /f /q "%DATADIR%\%%F" 2>nul
    )
)

REM Restore preserved files
for %%F in (wallet.dat DRAGONX.conf peers.dat) do (
    if exist "%TMPDIR%\%%F" (
        copy /y "%TMPDIR%\%%F" "%DATADIR%\%%F" >nul
    )
)
rmdir /s /q "%TMPDIR%" 2>nul

echo [INFO] Blockchain data cleaned.
exit /b 0

REM ============================================
REM  Download bootstrap (with fallback)
REM ============================================
:download_bootstrap
echo [INFO] Downloading bootstrap from %BOOTSTRAP_BASE_URL% ...
echo [INFO] This may take a while depending on your connection speed.

REM Try primary URL
call :do_download "%BOOTSTRAP_BASE_URL%"
if not errorlevel 1 goto :download_verify

echo [WARN] Primary download failed, trying fallback %BOOTSTRAP_FALLBACK_URL% ...
call :do_download "%BOOTSTRAP_FALLBACK_URL%"
if errorlevel 1 (
    echo [ERROR] Download failed from both primary and fallback servers.
    exit /b 1
)

:download_verify
echo [INFO] Bootstrap download complete.

REM Verify SHA256 checksum
echo [INFO] Verifying checksum...
pushd "%DATADIR%"

REM Read expected hash from the .sha256 file (format: "hash  filename" or "hash *filename")
set "EXPECTED_HASH="
for /f "tokens=1" %%A in (%BOOTSTRAP_FILE%.sha256) do (
    set "EXPECTED_HASH=%%A"
)

if "%EXPECTED_HASH%"=="" (
    echo [WARN] Could not read expected checksum, skipping verification.
    goto :verify_done
)

REM Use certutil to compute SHA256
certutil -hashfile "%BOOTSTRAP_FILE%" SHA256 > "%TEMP%\dragonx_hash.tmp" 2>nul
if errorlevel 1 (
    echo [WARN] certutil not available, skipping checksum verification.
    goto :verify_done
)

REM certutil outputs hash on the second line
set "ACTUAL_HASH="
set "LINE_NUM=0"
for /f "skip=1 tokens=*" %%H in (%TEMP%\dragonx_hash.tmp) do (
    if not defined ACTUAL_HASH (
        set "ACTUAL_HASH=%%H"
    )
)
REM Remove spaces from certutil output
set "ACTUAL_HASH=!ACTUAL_HASH: =!"
del /f /q "%TEMP%\dragonx_hash.tmp" 2>nul

if /i "!ACTUAL_HASH!"=="!EXPECTED_HASH!" (
    echo [INFO] SHA256 checksum verified.
) else (
    echo [ERROR] SHA256 checksum verification failed! The download may be corrupted.
    echo [ERROR] Expected: !EXPECTED_HASH!
    echo [ERROR] Got:      !ACTUAL_HASH!
    popd
    exit /b 1
)

:verify_done
REM Clean up checksum files
del /f /q "%BOOTSTRAP_FILE%.md5" 2>nul
del /f /q "%BOOTSTRAP_FILE%.sha256" 2>nul
popd
exit /b 0

REM ============================================
REM  Download files from a given base URL
REM  Usage: call :do_download "base_url"
REM ============================================
:do_download
set "BASE=%~1"

REM Use PowerShell to download (available on all modern Windows)
echo [INFO] Downloading %BASE%/%BOOTSTRAP_FILE% ...
powershell -NoProfile -Command ^
    "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; try { (New-Object Net.WebClient).DownloadFile('%BASE%/%BOOTSTRAP_FILE%', '%DATADIR%\%BOOTSTRAP_FILE%') } catch { exit 1 }"
if errorlevel 1 exit /b 1

echo [INFO] Downloading checksums...
powershell -NoProfile -Command ^
    "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; try { (New-Object Net.WebClient).DownloadFile('%BASE%/%BOOTSTRAP_FILE%.md5', '%DATADIR%\%BOOTSTRAP_FILE%.md5') } catch { exit 1 }"
if errorlevel 1 exit /b 1

powershell -NoProfile -Command ^
    "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; try { (New-Object Net.WebClient).DownloadFile('%BASE%/%BOOTSTRAP_FILE%.sha256', '%DATADIR%\%BOOTSTRAP_FILE%.sha256') } catch { exit 1 }"
if errorlevel 1 exit /b 1

exit /b 0

REM ============================================
REM  Extract bootstrap zip
REM ============================================
:extract_bootstrap
echo [INFO] Extracting bootstrap...
pushd "%DATADIR%"

REM Use PowerShell to extract zip, excluding wallet.dat and .conf files
powershell -NoProfile -Command ^
    "Add-Type -AssemblyName System.IO.Compression.FileSystem; $zip = [System.IO.Compression.ZipFile]::OpenRead('%DATADIR%\%BOOTSTRAP_FILE%'); foreach ($entry in $zip.Entries) { if ($entry.Name -eq 'wallet.dat' -or $entry.Name -like '*.conf') { continue } $dest = Join-Path '%DATADIR%' $entry.FullName; if ($entry.FullName.EndsWith('/')) { New-Item -ItemType Directory -Force -Path $dest | Out-Null } else { $parent = Split-Path $dest -Parent; if (-not (Test-Path $parent)) { New-Item -ItemType Directory -Force -Path $parent | Out-Null } [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $dest, $true) } }; $zip.Dispose()"
if errorlevel 1 (
    echo [ERROR] Extraction failed.
    popd
    exit /b 1
)

echo [INFO] Bootstrap extracted successfully.

REM Clean up archive
del /f /q "%BOOTSTRAP_FILE%" 2>nul
echo [INFO] Removed downloaded archive to save disk space.

popd
exit /b 0

:error_exit
echo.
echo [ERROR] Bootstrap installation failed.
exit /b 1
