@echo off
setlocal EnableExtensions EnableDelayedExpansion
title Redmine 6.0.6 One-shot Installer (Windows)

rem ==========================
rem Global variables
rem ==========================
set "REDMINE_VERSION=6.0.6"
set "REDMINE_ROOT=C:\redmine"
set "REDMINE_DIR=%REDMINE_ROOT%\redmine-%REDMINE_VERSION%"
set "REDMINE_ZIP=%TEMP%\redmine-%REDMINE_VERSION%.zip"
set "REDMINE_URL=https://www.redmine.org/releases/redmine-%REDMINE_VERSION%.zip"

rem --- Ruby 3.3.9-1 に固定 ---
set "RUBY_DIR=C:\Ruby33-x64"
set "RUBY_DL=%REDMINE_ROOT%\rubyinstaller-devkit-3.3.9-1-x64.exe"
set "RUBY_URL=https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-3.3.9-1/rubyinstaller-devkit-3.3.9-1-x64.exe"

set "PG_PREFIX=C:\Program Files\PostgreSQL\16"
set "PG_PORT=5432"
set "PG_URL=https://get.enterprisedb.com/postgresql/postgresql-16.10-1-windows-x64.exe"
set "PG_EXE=%REDMINE_ROOT%\postgresql-16.10-1-windows-x64.exe"
set "PG_SUPERUSER=postgres"
set "PG_SUPERPASSWORD=Postgres234"
set "PG_DATADIR=%PG_PREFIX%\data"
set "PG_SERVICE=postgresql-x64-16"

set "RM_DBNAME=redmine"
set "RM_DBUSER=redmine"
set "RM_DBPASS=redminepass"
set "RM_DBHOST=127.0.0.1"
set "RM_DBENC=UTF8"

set "NSSM_URL=https://nssm.cc/release/nssm-2.24.zip"
set "NSSM_ZIP=%REDMINE_ROOT%\nssm-2.24.zip"
set "NSSM_DIR=%REDMINE_ROOT%\nssm\nssm-2.24"
set "NSSM_EXE=%NSSM_DIR%\win64\nssm.exe"
set "PUMA_SERVICE=RedminePuma"

set "CURL=curl.exe"

rem ==========================
rem 1/16 Create working folders
rem ==========================
echo [1/16] Create working folders
if not exist "%REDMINE_ROOT%" mkdir "%REDMINE_ROOT%" || (echo ERROR: cannot create "%REDMINE_ROOT%" & exit /b 1)

rem ==========================
rem 2/16 Check tools (curl / PowerShell)
rem ==========================
echo [2/16] Check tools ^(curl / PowerShell^)
where "%CURL%" >nul 2>nul || (echo ERROR: curl not found in PATH & exit /b 1)
where powershell >nul 2>nul || (echo ERROR: PowerShell not found & exit /b 1)

rem ==========================
rem 3/16 RubyInstaller+Devkit (download if missing)
rem ==========================
echo [3/16] RubyInstaller+Devkit ^(download if missing^)
if exist "%RUBY_DIR%\bin\ruby.exe" (
  echo   - Ruby already installed.
) else (
  echo   - Ruby is not installed at "%RUBY_DIR%".
  echo   - Downloading RubyInstaller DevKit 3.4.5-1...
  "%CURL%" -fL --retry 3 --retry-connrefused -o "%RUBY_DL%" "%RUBY_URL%" || (
    echo ERROR: RubyInstaller download failed.
    exit /b 1
  )
)

rem ==========================
rem 4/16 Install Ruby silently to %RUBY_DIR%
rem ==========================
echo [4/16] Install Ruby silently to %RUBY_DIR%
if exist "%RUBY_DIR%\bin\ruby.exe" (
  echo   - Ruby already installed.
) else (
  if not defined RUBY_DL (
    for %%F in ("%REDMINE_ROOT%\rubyinstaller-devkit-*-x64.exe") do set "RUBY_DL=%%~fF"
  )
  if not exist "%RUBY_DL%" (
    echo ERROR: Ruby installer not found: "%RUBY_DL%"
    exit /b 1
  )
  echo   - Running RubyInstaller silently...
  start "" /wait "%RUBY_DL%" /verysilent /norestart /dir="%RUBY_DIR%" /tasks="assocfiles,modpath"
  if errorlevel 1 (
    echo ERROR: RubyInstaller failed with code %errorlevel%
    exit /b 1
  )
  if not exist "%RUBY_DIR%\bin\ruby.exe" (
    echo ERROR: Ruby did not appear at "%RUBY_DIR%\bin\ruby.exe"
    exit /b 1
  )
)

rem ==========================
rem 5/16 Bootstrap MSYS2/Devkit (skip updates for reproducibility)
rem ==========================
echo [5/16] Skip MSYS2/Devkit update for reproducibility
set "MSYSROOT=%RUBY_DIR%\msys64"
set "BASH_EXE=%MSYSROOT%\usr\bin\bash.exe"
if exist "%BASH_EXE%" (
  echo   - MSYS2 detected under Ruby, but updates are disabled ^(pinned environment^).
) else (
  echo   - MSYS2 not found under Ruby. Skipping.
)



rem ==========================
rem 6/16 PostgreSQL 16.10-1 (download if missing)
rem ==========================
echo [6/16] PostgreSQL 16.10-1 ^(download if missing^)
if exist "%PG_EXE%" (
  echo   - PostgreSQL installer already downloaded.
) else (
  echo   - Downloading:
  echo     URL: %PG_URL%
  echo     OUT: %PG_EXE%
  "%CURL%" -fL --retry 3 --retry-connrefused -o "%PG_EXE%" "%PG_URL%" || (
    echo ERROR: PostgreSQL download failed.
    exit /b 1
  )
)

rem ==========================
rem 7/16 Silent install PostgreSQL (server + CLI)
rem ==========================
echo [7/16] Silent install PostgreSQL ^(server + CLI^)
sc query "%PG_SERVICE%" | find /I "STATE" >nul 2>nul
if %errorlevel%==0 (
  echo   - PostgreSQL service already exists. skipping install.
) else (
  rem Preflight checks
  net session >nul 2>&1 || (echo ERROR: Need Administrator rights to install PostgreSQL. & exit /b 1)

  for /F "tokens=5" %%P in ('netstat -ano ^| find ":5432 " ^| find "LISTENING"') do set "PG_PID=%%P"
  if defined PG_PID (
    echo ERROR: TCP 5432 is in use by PID %PG_PID%.
    tasklist /FI "PID eq %PG_PID%"
    exit /b 1
  )

  if exist "%PG_DATADIR%\PG_VERSION" (
    echo ERROR: Existing data directory found: "%PG_DATADIR%"
    echo        Remove or rename it before reinstall.
    exit /b 1
  )

  echo   - Running installer silently...
  start "" /wait "%PG_EXE%" --mode unattended --unattendedmodeui minimal ^
    --prefix "%PG_PREFIX%" ^
    --datadir "%PG_DATADIR%" ^
    --superpassword "%PG_SUPERPASSWORD%" ^
    --servicename "%PG_SERVICE%" ^
    --serverport %PG_PORT% ^
    --install_runtimes 1

  if errorlevel 1 (
    echo ERROR: PostgreSQL install failed with code %errorlevel%
    exit /b 1
  )
)

rem ==========================
rem 8/16 Redmine %REDMINE_VERSION% (download/extract if needed)
rem ==========================
echo [8/16] Redmine %REDMINE_VERSION% ^(download/extract if needed^)
echo   - TARGET DIR: %REDMINE_DIR%
echo   - ZIP PATH  : %REDMINE_ZIP%
echo   - URL       : %REDMINE_URL%

if exist "%REDMINE_DIR%\config\database.yml.example" (
  echo   - Redmine already extracted.
) else (
  if exist "%REDMINE_ZIP%" (
    echo   - Redmine zip already downloaded.
  ) else (
    echo   - Downloading Redmine...
    "%CURL%" -fL --retry 3 --retry-connrefused -o "%REDMINE_ZIP%" "%REDMINE_URL%" || (
      echo ERROR: Redmine download failed.
      exit /b 1
    )
  )
  if not exist "%REDMINE_ROOT%" mkdir "%REDMINE_ROOT%" || (echo ERROR: cannot create %REDMINE_ROOT% & exit /b 1)
  powershell -NoLogo -NoProfile -Command ^
    "Expand-Archive -LiteralPath '%REDMINE_ZIP%' -DestinationPath '%REDMINE_ROOT%' -Force" || (
      echo ERROR: Expand-Archive failed.
      exit /b 1
    )
  if not exist "%REDMINE_DIR%" (
    echo ERROR: Expected folder "%REDMINE_DIR%" not found after extraction.
    dir /b "%REDMINE_ROOT%"
    exit /b 1
  )
)


rem ==========================
rem 9/16 Create DB and user (UTF-8 safe; idempotent)
rem ==========================
echo [9/16] Create DB and user ^(UTF-8 safe; idempotent^)
set "PG_BIN=%PG_PREFIX%\bin"
if not exist "%PG_BIN%\psql.exe" (
  echo ERROR: psql not found at "%PG_BIN%\psql.exe"
  exit /b 1
)

set "PGPASSWORD=%PG_SUPERPASSWORD%"
set "PGCLIENTENCODING=UTF8"

rem Create role if not exists (idempotent)
set "SQL_ROLE=%TEMP%\create_role.sql"
> "%SQL_ROLE%" echo DO $$
>>"%SQL_ROLE%" echo BEGIN
>>"%SQL_ROLE%" echo   IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = '%RM_DBUSER%') THEN
>>"%SQL_ROLE%" echo     CREATE ROLE %RM_DBUSER% LOGIN PASSWORD '%RM_DBPASS%';
>>"%SQL_ROLE%" echo   END IF;
>>"%SQL_ROLE%" echo END
>>"%SQL_ROLE%" echo $$;

"%PG_BIN%\psql.exe" -h "%RM_DBHOST%" -U "%PG_SUPERUSER%" -p %PG_PORT% -d postgres -v ON_ERROR_STOP=1 -f "%SQL_ROLE%" || (
  del "%SQL_ROLE%" 2>nul
  set "PGPASSWORD=" & set "PGCLIENTENCODING="
  echo ERROR: role creation failed
  exit /b 1
)
del "%SQL_ROLE%" 2>nul

rem ★ 既存ロールでも必ずパスワードを RM_DBPASS に統一する
set "SQL_ROLE_FORCE=%TEMP%\alter_role.sql"
> "%SQL_ROLE_FORCE%" echo ALTER ROLE %RM_DBUSER% WITH LOGIN PASSWORD '%RM_DBPASS%';
"%PG_BIN%\psql.exe" -h "%RM_DBHOST%" -U "%PG_SUPERUSER%" -p %PG_PORT% -d postgres -v ON_ERROR_STOP=1 -f "%SQL_ROLE_FORCE%" || (
  del "%SQL_ROLE_FORCE%" 2>nul
  set "PGPASSWORD=" & set "PGCLIENTENCODING="
  echo ERROR: alter role failed
  exit /b 1
)
del "%SQL_ROLE_FORCE%" 2>nul

rem Check DB existence in a robust way
set "DBCHK=%TEMP%\db_exists.out"
"%PG_BIN%\psql.exe" -h "%RM_DBHOST%" -U "%PG_SUPERUSER%" -p %PG_PORT% -d postgres -t -A -v ON_ERROR_STOP=1 ^
  -c "SELECT CASE WHEN EXISTS (SELECT 1 FROM pg_database WHERE datname='%RM_DBNAME%') THEN 'EXISTS' ELSE 'MISSING' END;" > "%DBCHK%" 2>nul
if errorlevel 1 (
  del "%DBCHK%" 2>nul
  echo ERROR: failed to check database existence
  set "PGCLIENTENCODING=" & set "PGPASSWORD="
  exit /b 1
)
set "DBSTATE="
set /p DBSTATE=<"%DBCHK%"
del "%DBCHK%" 2>nul

if /I "%DBSTATE%"=="EXISTS" (
  echo   - Database %RM_DBNAME% already exists. skipping create.
) else (
  echo   - Creating database %RM_DBNAME% ...
  "%PG_BIN%\createdb.exe" -h "%RM_DBHOST%" -U "%PG_SUPERUSER%" -p %PG_PORT% -E %RM_DBENC% -O %RM_DBUSER% "%RM_DBNAME%" || (
    echo ERROR: database creation failed
    set "PGCLIENTENCODING=" & set "PGPASSWORD="
    exit /b 1
  )
)

rem ★ DB の所有者を redmine に明示（既に所有でも成功）
"%PG_BIN%\psql.exe" -h "%RM_DBHOST%" -U "%PG_SUPERUSER%" -p %PG_PORT% -d postgres -v ON_ERROR_STOP=1 ^
  -c "ALTER DATABASE %RM_DBNAME% OWNER TO %RM_DBUSER%;" || (
    echo ERROR: alter database owner failed
    set "PGCLIENTENCODING=" & set "PGPASSWORD="
    exit /b 1
  )

rem ★ redmine 資格情報での実接続テスト（ここで落ちるなら先へ進まない）
set "PGPASSWORD=%RM_DBPASS%"
"%PG_BIN%\psql.exe" -h "%RM_DBHOST%" -U "%RM_DBUSER%" -p %PG_PORT% -d "%RM_DBNAME%" -t -A -c "select current_user||'@'||current_database();" || (
  echo ERROR: redmine user cannot connect with provided password.
  set "PGCLIENTENCODING=" & set "PGPASSWORD="
  exit /b 1
)

set "PGCLIENTENCODING=" & set "PGPASSWORD="



rem ==========================
rem 10/16 Write config/database.yml
rem ==========================
echo [10/16] Write config/database.yml
set "DBYML=%REDMINE_DIR%\config\database.yml"

powershell -NoLogo -NoProfile -Command "$lines=@('production:','  adapter: postgresql','  database: %RM_DBNAME%','  host: %RM_DBHOST%','  port: %PG_PORT%','  username: %RM_DBUSER%','  password: %RM_DBPASS%','  encoding: %RM_DBENC%','  sslmode: disable'); $enc=New-Object System.Text.UTF8Encoding($false); [IO.File]::WriteAllLines('%DBYML%', $lines, $enc)" || (
  echo ERROR: write database.yml failed
  exit /b 1
)



rem ==========================
rem 11/16 Ensure Gemfile.local (link only; no puma ops here)
rem ==========================
echo [11/16] Ensure Gemfile.local
set "GEMFILE=%REDMINE_DIR%\Gemfile"
set "GEMLOCAL=%REDMINE_DIR%\Gemfile.local"

if not exist "%GEMLOCAL%" type NUL > "%GEMLOCAL%"

rem Gemfile に eval_gemfile が無ければ追加
findstr /C:"eval_gemfile 'Gemfile.local'" "%GEMFILE%" >nul 2>&1 || (
  echo eval_gemfile 'Gemfile.local'>>"%GEMFILE%"
)

echo   - Linked Gemfile.local from Gemfile




rem ==========================
rem 12/16 Install gems (vendor/bundle; production only)
rem ==========================
echo [12/16] Install gems ^(vendor/bundle; production only^)
cd /d "%REDMINE_DIR%" || (echo ERROR: cd failed & exit /b 1)

rem --- Ensure Redmine ZIP exists (for Gemfile restore) ---
if not exist "%REDMINE_ZIP%" (
  echo   - Redmine zip not found. Downloading...
  "%CURL%" -fL --retry 3 --retry-connrefused -o "%REDMINE_ZIP%" "%REDMINE_URL%" || (
    echo ERROR: Redmine download failed.
    exit /b 1
  )
)

rem --- Restore pristine Gemfile from ZIP (no full re-extract) ---
set "GEMFILE=%REDMINE_DIR%\Gemfile"
set "GEMLOCAL=%REDMINE_DIR%\Gemfile.local"
powershell -NoLogo -NoProfile -Command ^
  "$zip='%REDMINE_ZIP%'; $dest='%GEMFILE%'; $ver='%REDMINE_VERSION%';" ^
  "Add-Type -AssemblyName System.IO.Compression.FileSystem;" ^
  "$z=[IO.Compression.ZipFile]::OpenRead($zip);" ^
  "try {" ^
  "  $entry=$z.Entries | Where-Object { $_.FullName -like ('redmine-'+$ver+'/Gemfile') };" ^
  "  if(-not $entry){ Write-Error 'Gemfile entry not found in zip.'; exit 1 }" ^
  "  $fs=[IO.File]::Open($dest,[IO.FileMode]::Create,[IO.FileAccess]::Write,[IO.FileShare]::None);" ^
  "  try { $entry.Open().CopyTo($fs) } finally { $fs.Dispose() }" ^
  "} finally { $z.Dispose() }" || (
  echo ERROR: failed to restore Gemfile from zip
  exit /b 1
)

rem --- Dedupe & pin puma AFTER Gemfile restore ---
powershell -NoLogo -NoProfile -Command ^
  "$gf='%GEMFILE%'; $gl='%GEMLOCAL%'; $enc=New-Object System.Text.UTF8Encoding($false);" ^
  "$rx = '^\s*gem\s+[''^""]puma[''^""]';" ^
  "function Sanitize([string]$path) {" ^
  "  if (Test-Path -LiteralPath $path) {" ^
  "    $t = Get-Content -LiteralPath $path -Raw -ErrorAction SilentlyContinue;" ^
  "    if ($null -eq $t) { $lines = @() } else { $lines = ($t -split \"`r?`n\") | Where-Object { $_ -notmatch $rx } }" ^
  "    [IO.File]::WriteAllLines($path, [string[]]$lines, $enc)" ^
  "  }" ^
  "}" ^
  "Sanitize $gf; Sanitize $gl; " ^
  "Add-Content -LiteralPath $gl -Value \"gem 'puma', '6.6.1', group: :production\"" || (
  echo ERROR: failed to finalize puma entries
  exit /b 1
)
echo   - Ensured single puma entry in Gemfile.local (production)

rem --- Ensure MSYS2 packages for native gems (psych/libyaml) ---
set "RIDK=%RUBY_DIR%\bin\ridk.cmd"
if exist "%RIDK%" (
  call "%RIDK%" exec bash -lc "pacman -Sy --noconfirm && pacman -S --noconfirm --needed mingw-w64-ucrt-x86_64-libyaml mingw-w64-ucrt-x86_64-pkgconf mingw-w64-ucrt-x86_64-toolchain" || (
    echo ERROR: MSYS2 packages install failed & exit /b 1
  )
) else (
  echo WARNING: ridk.cmd not found; native gems may fail to compile.
)

rem --- Make pkg-config/libyaml visible during build ---
set "OLDPATH_BUND=%PATH%"
set "PATH=%RUBY_DIR%\msys64\ucrt64\bin;%RUBY_DIR%\msys64\usr\bin;%PATH%"
set "PKG_CONFIG_PATH=%RUBY_DIR%\msys64\ucrt64\lib\pkgconfig"

rem --- Bundler settings & cleanup (過去の deployment/frozen を解除) ---
call "%RUBY_DIR%\bin\bundle.bat" config unset deployment >nul 2>&1
call "%RUBY_DIR%\bin\bundle.bat" config unset frozen     >nul 2>&1
call "%RUBY_DIR%\bin\bundle.bat" config set deployment false
call "%RUBY_DIR%\bin\bundle.bat" config set frozen     false
call "%RUBY_DIR%\bin\bundle.bat" config set clean      true
call "%RUBY_DIR%\bin\bundle.bat" config set path "vendor/bundle"       || (echo ERROR: bundle config path failed & exit /b 1)
call "%RUBY_DIR%\bin\bundle.bat" config set without "development test" || (echo ERROR: bundle config without failed & exit /b 1)
if exist "vendor\cache" rmdir /S /Q "vendor\cache" >nul 2>&1

echo   - Installing with resolved dependencies...
call "%RUBY_DIR%\bin\bundle.bat" install --jobs 4 --retry 3 || (echo ERROR: bundle install failed & exit /b 1)

rem --- Ensure puma is really present (production) ---
call "%RUBY_DIR%\bin\bundle.bat" show puma >nul 2>&1
if errorlevel 1 (
  echo   - Puma not found; adding for production...
  call "%RUBY_DIR%\bin\bundle.bat" add puma --skip-install --group production || (echo ERROR: bundle add puma failed & exit /b 1)
  call "%RUBY_DIR%\bin\bundle.bat" install --jobs 4 --retry 3 || (echo ERROR: bundle install for puma failed & exit /b 1)
)

rem Add Windows platform to the lockfile (does not change versions)
call "%RUBY_DIR%\bin\bundle.bat" lock --add-platform x64-mingw-ucrt >nul 2>&1

rem Rebuild vendor/cache
call "%RUBY_DIR%\bin\bundle.bat" package || (echo ERROR: bundle package failed & exit /b 1)

rem deployment/frozen を最後に戻す（以後は変更不可の固定運用）
call "%RUBY_DIR%\bin\bundle.bat" config set deployment true  >nul 2>&1
call "%RUBY_DIR%\bin\bundle.bat" config set frozen     true  >nul 2>&1

rem --- Extra: 強制的にサービス環境向けに vendor/bundle に固定 ---
call "%RUBY_DIR%\bin\bundle.bat" config set --local path "vendor/bundle"
call "%RUBY_DIR%\bin\bundle.bat" config set --local without "development test"
call "%RUBY_DIR%\bin\bundle.bat" config set --local deployment true
call "%RUBY_DIR%\bin\bundle.bat" install --jobs 4 --retry 3 || (
  echo ERROR: bundle install for service environment failed & exit /b 1
)

rem --- Restore PATH after native build ---
if defined OLDPATH_BUND set "PATH=%OLDPATH_BUND%"









rem ==========================
rem 13/16 DB migrate & assets precompile
rem ==========================
echo [13/16] DB migrate ^& assets precompile
set "OLDPATH=%PATH%"
rem Use Ruby only here (avoid mixing libpq from server)
set "PATH=%RUBY_DIR%\bin;%PATH%"
rem ★ TLS を無効化して切り分け/恒久回避
set "PGSSLMODE=disable"

cd /d "%REDMINE_DIR%" || (echo ERROR: cd failed & set "PATH=%OLDPATH%" & exit /b 1)

call "%RUBY_DIR%\bin\bundle.bat" exec rake generate_secret_token RAILS_ENV=production || (echo ERROR: generate_secret_token failed & set "PATH=%OLDPATH%" & exit /b 1)
call "%RUBY_DIR%\bin\bundle.bat" exec rake db:migrate           RAILS_ENV=production || (echo ERROR: db:migrate failed & set "PATH=%OLDPATH%" & exit /b 1)
call "%RUBY_DIR%\bin\bundle.bat" exec rake assets:precompile    RAILS_ENV=production || (echo ERROR: assets:precompile failed & set "PATH=%OLDPATH%" & exit /b 1)

set "PATH=%OLDPATH%"




rem ==========================
rem 14/16 Get/prepare NSSM
rem ==========================
echo [14/16] Get/prepare NSSM
if exist "%NSSM_EXE%" (
  echo   - NSSM already present.
) else (
  echo   - Downloading NSSM 2.24...
  "%CURL%" -fL --retry 3 --retry-connrefused -o "%NSSM_ZIP%" "%NSSM_URL%" || (echo ERROR: NSSM download failed & exit /b 1)
  if not exist "%REDMINE_ROOT%\nssm" mkdir "%REDMINE_ROOT%\nssm"
  powershell -NoLogo -NoProfile -Command "Expand-Archive -LiteralPath '%NSSM_ZIP%' -DestinationPath '%REDMINE_ROOT%\nssm' -Force" || (
    echo ERROR: Expand-Archive NSSM failed
    exit /b 1
  )
  if not exist "%NSSM_EXE%" (
    echo ERROR: NSSM exe not found at "%NSSM_EXE%"
    exit /b 1
  )
)



rem ==========================
rem 15/16 Register/Configure Puma service
rem ==========================
echo [15/16] Register/Configure Puma service

rem --- ラッパー BAT を作成（環境変数をここで完結）---
set "RUNBAT=%REDMINE_DIR%\run_puma_service.bat"
>  "%RUNBAT%" echo @echo off
>> "%RUNBAT%" echo setlocal EnableExtensions
>> "%RUNBAT%" echo cd /d "%REDMINE_DIR%"
>> "%RUNBAT%" echo set "RAILS_ENV=production"
>> "%RUNBAT%" echo set "BUNDLE_WITHOUT=development:test"
>> "%RUNBAT%" echo set "BUNDLE_DEPLOYMENT=1"
>> "%RUNBAT%" echo set "BUNDLE_FROZEN=1"
>> "%RUNBAT%" echo set "BUNDLE_PATH=vendor/bundle"
>> "%RUNBAT%" echo set "BUNDLE_GEMFILE=%REDMINE_DIR%\Gemfile"
>> "%RUNBAT%" echo set "PATH=%RUBY_DIR%\bin;%PG_PREFIX%\bin;%%PATH%%"
>> "%RUNBAT%" echo if not exist "log" mkdir "log"
>> "%RUNBAT%" echo call "%RUBY_DIR%\bin\bundle.bat" exec puma -C config\puma.rb

rem --- ログ用ディレクトリ ---
if not exist "%REDMINE_DIR%\log"         mkdir "%REDMINE_DIR%\log"
if not exist "%REDMINE_DIR%\tmp"         mkdir "%REDMINE_DIR%\tmp"
if not exist "%REDMINE_DIR%\tmp\pids"    mkdir "%REDMINE_DIR%\tmp\pids"
if not exist "%REDMINE_DIR%\tmp\sockets" mkdir "%REDMINE_DIR%\tmp\sockets"

rem --- puma.rb を上書き（必要最小限・フォアグラウンドで実行）---
copy /Y "%REDMINE_DIR%\config\puma.rb" "%REDMINE_DIR%\config\puma.rb.bak" >nul 2>nul
>  "%REDMINE_DIR%\config\puma.rb" echo environment ENV.fetch("RAILS_ENV","production")
>> "%REDMINE_DIR%\config\puma.rb" echo workers 0
>> "%REDMINE_DIR%\config\puma.rb" echo threads_count = Integer(ENV.fetch("RAILS_MAX_THREADS","5"))
>> "%REDMINE_DIR%\config\puma.rb" echo threads threads_count, threads_count
>> "%REDMINE_DIR%\config\puma.rb" echo bind "tcp://127.0.0.1:3000"
>> "%REDMINE_DIR%\config\puma.rb" echo pidfile "tmp/pids/puma.pid"
>> "%REDMINE_DIR%\config\puma.rb" echo state_path "tmp/pids/puma.state"
>> "%REDMINE_DIR%\config\puma.rb" echo stdout_redirect "log/puma.stdout.log","log/puma.stderr.log", true
>> "%REDMINE_DIR%\config\puma.rb" echo plugin :tmp_restart

rem --- NSSM サービス作成／再設定 ---
sc query "%PUMA_SERVICE%" >nul 2>nul || (
  "%NSSM_EXE%" install "%PUMA_SERVICE%" "%SystemRoot%\System32\cmd.exe"
  if errorlevel 1 (echo ERROR: nssm install failed & exit /b 1)
)

rem ★ 重要：必ず Application=cmd.exe にする（旧設定の ruby.exe を上書き）
"%NSSM_EXE%" set "%PUMA_SERVICE%" Application "%SystemRoot%\System32\cmd.exe"

rem パラメータは /c "runbat" の形に（正しいクォート）
"%NSSM_EXE%" set "%PUMA_SERVICE%" AppParameters /c "\"%RUNBAT%\""

"%NSSM_EXE%" set "%PUMA_SERVICE%" AppDirectory "%REDMINE_DIR%"
"%NSSM_EXE%" set "%PUMA_SERVICE%" AppStdout "%REDMINE_DIR%\log\puma.nssm.out.log"
"%NSSM_EXE%" set "%PUMA_SERVICE%" AppStderr "%REDMINE_DIR%\log\puma.nssm.err.log"
"%NSSM_EXE%" set "%PUMA_SERVICE%" AppNoConsole 1
"%NSSM_EXE%" set "%PUMA_SERVICE%" AppStopMethodConsole 5000

rem ==========================
rem 16/16 Start service and open browser
rem ==========================
echo [16/16] Start service and open browser

rem 既存インスタンス停止（無視して続行）
"%NSSM_EXE%" stop "%PUMA_SERVICE%" >nul 2>nul

rem 起動
"%NSSM_EXE%" start "%PUMA_SERVICE%" || (
  echo ERROR: failed to start service
  goto :_svc_diag
)

rem ステータス表示
sc query "%PUMA_SERVICE%"

start "" "http://127.0.0.1:3000/"
echo DONE. Redmine should be at: http://127.0.0.1:3000/
echo Default login: admin / admin
goto :eof

:_svc_diag
echo --- NSSM / Puma diagnostics (last 200 lines) ---
powershell -NoLogo -NoProfile -Command ^
  "foreach($f in @('%REDMINE_DIR%\log\puma.nssm.err.log','%REDMINE_DIR%\log\puma.nssm.out.log','%REDMINE_DIR%\log\puma.stderr.log','%REDMINE_DIR%\log\puma.stdout.log')){ if(Test-Path $f){Write-Host '--- ' $f ' ---'; Get-Content -LiteralPath $f -Tail 200 } }"
exit /b 1
