#Requires -RunAsAdministrator
# Same as RentRoom 2026 (proven on customer machines)
param(
    [string]$InstanceName = 'SQLEXPRESS',
    [string]$SaPassword = '1qaz@WSX',
    [string]$DownloadUrl = 'https://go.microsoft.com/fwlink/?linkid=866658',
    [string]$WorkDir = $env:TEMP
)

$ErrorActionPreference = 'Stop'

function Enable-Tls12 {
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
}

function Download-File {
    param([string]$Url, [string]$OutFile)
    Enable-Tls12
    try {
        Invoke-WebRequest -Uri $Url -OutFile $OutFile -UseBasicParsing
    }
    catch {
        $curl = Join-Path $env:SystemRoot 'System32\curl.exe'
        if (-not (Test-Path $curl)) { throw }
        & $curl -fL --retry 3 -o $OutFile $Url
        if ($LASTEXITCODE -ne 0) { throw "curl download failed: $Url" }
    }
}

function Test-SqlExpressInstance {
    param([string]$Name)
    $regPath = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL'
    if (-not (Test-Path $regPath)) { return $false }
    $value = Get-ItemProperty -Path $regPath -Name $Name -ErrorAction SilentlyContinue
    return ($null -ne $value)
}

function Wait-ForSqlService {
    param([string]$Instance, [int]$TimeoutSec = 900)
    $serviceName = "MSSQL`$$Instance"
    $sw = [Diagnostics.Stopwatch]::StartNew()
    while ($sw.Elapsed.TotalSeconds -lt $TimeoutSec) {
        $svc = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
        if ($svc -and $svc.Status -eq 'Running') {
            Start-Sleep -Seconds 5
            return $true
        }
        Start-Sleep -Seconds 3
    }
    throw "SQL service '$serviceName' did not start within $TimeoutSec seconds."
}

if (Test-SqlExpressInstance -Name $InstanceName) {
    Write-Host "SQL instance '$InstanceName' already exists."
    exit 0
}

if (-not (Test-Path $WorkDir)) {
    New-Item -ItemType Directory -Path $WorkDir -Force | Out-Null
}

$bootstrapExe = Join-Path $WorkDir 'SQL2019-SSEI-Expr.exe'
$mediaPath = Join-Path $WorkDir 'SQL2019_Express_Media'

Write-Host 'Downloading SQL Server 2019 Express bootstrap...'
Download-File -Url $DownloadUrl -OutFile $bootstrapExe

if (-not (Test-Path $mediaPath)) {
    New-Item -ItemType Directory -Path $mediaPath -Force | Out-Null
}

Write-Host 'Downloading SQL Server installation media (several minutes)...'
$downloadArgs = @(
    '/ACTION=Download',
    '/MEDIATYPE=Core',
    "/MEDIAPATH=$mediaPath",
    '/QUIET'
)
$proc = Start-Process -FilePath $bootstrapExe -ArgumentList $downloadArgs -Wait -PassThru -NoNewWindow
if ($proc.ExitCode -ne 0) {
    throw "SQL media download failed. ExitCode=$($proc.ExitCode)"
}

$exprExe = Get-ChildItem -Path $mediaPath -Filter 'SQLEXPR*.exe' -Recurse -ErrorAction SilentlyContinue |
    Select-Object -First 1
if (-not $exprExe) {
    throw "SQLEXPR installer not found under $mediaPath after download."
}

$extractPath = Join-Path $mediaPath 'setup_media'
if (-not (Test-Path $extractPath)) {
    New-Item -ItemType Directory -Path $extractPath -Force | Out-Null
}

$setupExe = Get-ChildItem -Path $extractPath -Filter 'setup.exe' -Recurse -ErrorAction SilentlyContinue |
    Select-Object -First 1
if (-not $setupExe) {
    Write-Host "Extracting $($exprExe.Name)..."
    $extractArgs = @('/q', "/x:$extractPath")
    $proc = Start-Process -FilePath $exprExe.FullName -ArgumentList $extractArgs -Wait -PassThru -NoNewWindow
    if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
        throw "SQLEXPR extract failed. ExitCode=$($proc.ExitCode)"
    }
    $setupExe = Get-ChildItem -Path $extractPath -Filter 'setup.exe' -Recurse -ErrorAction SilentlyContinue |
        Select-Object -First 1
}

if (-not $setupExe) {
    $setupExe = Get-ChildItem -Path $mediaPath -Filter 'setup.exe' -Recurse -ErrorAction SilentlyContinue |
        Select-Object -First 1
}
if (-not $setupExe) {
    throw "setup.exe not found under $mediaPath"
}
$setupExe = $setupExe.FullName

Write-Host "Installing SQL Server Express '$InstanceName' (silent)..."
$installArgs = @(
    '/QS',
    '/ACTION=Install',
    '/FEATURES=SQLEngine',
    "/INSTANCENAME=$InstanceName",
    '/SQLSVCSTARTUPTYPE=Automatic',
    '/SQLSYSADMINACCOUNTS=BUILTIN\Administrators',
    '/SECURITYMODE=SQL',
    "/SAPWD=$SaPassword",
    '/IACCEPTSQLSERVERLICENSETERMS'
)
$proc = Start-Process -FilePath $setupExe -ArgumentList $installArgs -Wait -PassThru -NoNewWindow
if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
    throw "SQL Express install failed. ExitCode=$($proc.ExitCode)"
}

Wait-ForSqlService -Instance $InstanceName
Write-Host 'SQL Server 2019 Express OK.'
exit 0
