<#
============================================================================
MaxUserBenchmarkTest - Windows Launcher (PowerShell)
============================================================================
This script sets up the environment and launches the database benchmark test
using the bundled Java runtime and JMeter installation.

Configuration is read from config/appsettings.json

Usage:
  .\run.ps1 [-ConfigName <config_name>] [-ConfigFile <path_to_config.json>]

Parameters:
  -ConfigName    Name of the database configuration from the JSON file (e.g., "oracle", "postgres", "oracle-qa")
                 If not provided and only one config exists, uses that automatically.
                 If multiple configs exist, prompts user to select.
  -ConfigFile    Optional path to custom config file (defaults to config/appsettings.json)

Examples:
  .\run.ps1                                    # Auto-select if only one config, or prompt if multiple
  .\run.ps1 -ConfigName oracle                 # Use specific config
  .\run.ps1 -ConfigName postgres-dev
  .\run.ps1 -ConfigName oracle-qa -ConfigFile config/my-custom-config.json
============================================================================
#>

param(
    [Parameter(Mandatory=$false, HelpMessage="Name of the database configuration from the JSON file")]
    [string]$ConfigName,
    
    [Parameter(Mandatory=$false)]
    [string]$ConfigFile = "config\appsettings.json"
)

# Display header
Write-Host ""
Write-Host "============================================================================" -ForegroundColor Cyan
Write-Host "MaxUserBenchmarkTest - Database Benchmark Tool" -ForegroundColor Cyan
Write-Host "============================================================================" -ForegroundColor Cyan
Write-Host ""

# Capture the start timestamp when the script first runs
$ScriptStartTime = Get-Date

# Get the directory where this script is located
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path

# Import encryption module (similar to migrate.ps1)
# Helper is located in tools\helper\ relative to the repository root, or in helper\ relative to script when packaged
$toolsRoot = Split-Path -Parent $ScriptDir
$encryptionModule = Join-Path $toolsRoot "helper\Helper-Encryption.psm1"

# If not found at tools root, try relative to script directory (for packaged artifact)
if (-not (Test-Path $encryptionModule)) {
    $encryptionModule = Join-Path $ScriptDir "helper\Helper-Encryption.psm1"
}

if (Test-Path $encryptionModule) {
    try {
        Import-Module $encryptionModule -Force
    } catch {
        Write-Host "WARNING: Could not import encryption module: $($_.Exception.Message)" -ForegroundColor Yellow
        Write-Host "Passwords will not be encrypted/decrypted." -ForegroundColor Yellow
    }
} else {
    Write-Host "WARNING: Encryption module not found. Tried:" -ForegroundColor Yellow
    Write-Host "  - $encryptionModule" -ForegroundColor Yellow
    Write-Host "Passwords will not be encrypted/decrypted." -ForegroundColor Yellow
}

# Load configuration file
$ConfigPath = if ([System.IO.Path]::IsPathRooted($ConfigFile)) {
    $ConfigFile
} else {
    Join-Path $ScriptDir $ConfigFile
}

if (-not (Test-Path $ConfigPath)) {
    Write-Host "ERROR: Configuration file not found at $ConfigPath" -ForegroundColor Red
    Write-Host "Please create a config file or use the sample: config\appsettings.json" -ForegroundColor Yellow
    Write-Host ""
    Read-Host "Press Enter to exit"
    exit 1
}

Write-Host "Loading configuration from: $ConfigPath" -ForegroundColor Green

# Check for and convert any plaintext passwords (similar to migrate.ps1)
$null = Convert-PlaintextPasswordsInJson -JsonFilePath $ConfigPath

try {
    $Config = Get-Content $ConfigPath -Raw | ConvertFrom-Json
    # Decrypt password properties (similar to migrate.ps1)
    $Config = Unprotect-JsonPasswords -JsonObject $Config
} catch {
    Write-Host "ERROR: Failed to parse configuration file" -ForegroundColor Red
    Write-Host $_.Exception.Message -ForegroundColor Red
    Write-Host ""
    Read-Host "Press Enter to exit"
    exit 1
}

# Get available database configurations
$AvailableConfigs = @($Config.databases.PSObject.Properties.Name)

if ($AvailableConfigs.Count -eq 0) {
    Write-Host "ERROR: No database configurations found in $ConfigPath" -ForegroundColor Red
    Write-Host "Please add at least one database configuration to the 'databases' section." -ForegroundColor Yellow
    Write-Host ""
    Read-Host "Press Enter to exit"
    exit 1
}

# Determine which config to use
if ([string]::IsNullOrWhiteSpace($ConfigName)) {
    if ($AvailableConfigs.Count -eq 1) {
        # Auto-select the only available config
        $ConfigName = $AvailableConfigs[0]
        Write-Host "Auto-selected configuration: $ConfigName (only one available)" -ForegroundColor Cyan
        Write-Host ""
    } else {
        # Multiple configs available - prompt user
        Write-Host "Multiple database configurations available:" -ForegroundColor Yellow
        for ($i = 0; $i -lt $AvailableConfigs.Count; $i++) {
            Write-Host "  [$($i + 1)] $($AvailableConfigs[$i])" -ForegroundColor Yellow
        }
        Write-Host ""
        
        do {
            $selection = Read-Host "Select a configuration (1-$($AvailableConfigs.Count)) or press Ctrl+C to cancel"
            $selectionNum = 0
            $validSelection = [int]::TryParse($selection, [ref]$selectionNum) -and 
                              $selectionNum -ge 1 -and 
                              $selectionNum -le $AvailableConfigs.Count
            
            if (-not $validSelection) {
                Write-Host "Invalid selection. Please enter a number between 1 and $($AvailableConfigs.Count)." -ForegroundColor Red
            }
        } while (-not $validSelection)
        
        $ConfigName = $AvailableConfigs[$selectionNum - 1]
        Write-Host ""
    }
}

# Verify the selected configuration exists
if (-not $Config.databases.PSObject.Properties.Name -contains $ConfigName) {
    Write-Host "ERROR: Configuration '$ConfigName' not found in $ConfigPath" -ForegroundColor Red
    Write-Host "Available configurations:" -ForegroundColor Yellow
    $AvailableConfigs | ForEach-Object { Write-Host "  - $_" -ForegroundColor Yellow }
    Write-Host ""
    Read-Host "Press Enter to exit"
    exit 1
}

$DbConfig = $Config.databases.$ConfigName
Write-Host "Using database configuration: $ConfigName" -ForegroundColor Green
Write-Host "  Type: $($DbConfig.type)" -ForegroundColor Gray
Write-Host "  URL: $($DbConfig.url)" -ForegroundColor Gray
Write-Host "  User: $($DbConfig.username)" -ForegroundColor Gray
Write-Host ""

# Set JAVA_HOME to the bundled JRE
$env:JAVA_HOME = Join-Path $ScriptDir "jre"
$env:PATH = "$env:JAVA_HOME\bin;$env:PATH"

# Verify Java is available
$JavaExe = Join-Path $env:JAVA_HOME "bin\java.exe"
if (-not (Test-Path $JavaExe)) {
    Write-Host "ERROR: Java runtime not found at $env:JAVA_HOME" -ForegroundColor Red
    Write-Host "Please ensure the jre folder exists in the installation directory." -ForegroundColor Red
    Write-Host ""
    Read-Host "Press Enter to exit"
    exit 1
}

# Display Java version
Write-Host "Using bundled Java:" -ForegroundColor Green
$javaVersion = & $JavaExe -version 2>&1 | Select-String "version"
Write-Host $javaVersion
Write-Host ""

# Verify JMeter exists
$JMeterBat = Join-Path $ScriptDir "jmeter\bin\jmeter.bat"
if (-not (Test-Path $JMeterBat)) {
    Write-Host "ERROR: JMeter not found at $ScriptDir\jmeter" -ForegroundColor Red
    Write-Host "Please ensure the jmeter folder exists in the installation directory." -ForegroundColor Red
    Write-Host ""
    Read-Host "Press Enter to exit"
    exit 1
}

# Verify test scripts exist
$BenchmarkScript = Join-Path $ScriptDir "test\benchmark_test.ps1"
if (-not (Test-Path $BenchmarkScript)) {
    Write-Host "ERROR: Test scripts not found at $ScriptDir\test" -ForegroundColor Red
    Write-Host "Please ensure the test folder exists in the installation directory." -ForegroundColor Red
    Write-Host ""
    Read-Host "Press Enter to exit"
    exit 1
}

# Change to test directory
$TestDir = Join-Path $ScriptDir "test"
Set-Location $TestDir

# Build arguments to pass to benchmark script from config
$BenchmarkArgs = @{
    Database = $DbConfig.type
    DbUser = $DbConfig.username
    DbPass = $DbConfig.password
    DbUrl = $DbConfig.url
    ScriptStartTime = $ScriptStartTime
}

# Run the PowerShell benchmark script
Write-Host "Starting benchmark test..." -ForegroundColor Green
Write-Host ""

try {
    & $BenchmarkScript @BenchmarkArgs
    $ExitCode = $LASTEXITCODE
} catch {
    Write-Host "ERROR: Failed to run benchmark test" -ForegroundColor Red
    Write-Host $_.Exception.Message -ForegroundColor Red
    $ExitCode = 1
}

# Display completion message
Write-Host ""
Write-Host "============================================================================" -ForegroundColor Cyan
Write-Host "Test completed with exit code: $ExitCode" -ForegroundColor $(if ($ExitCode -eq 0) { "Green" } else { "Red" })
Write-Host "============================================================================" -ForegroundColor Cyan
Write-Host ""

Read-Host "Press Enter to exit"
exit $ExitCode
