<#
.SYNOPSIS
    Idempotent migration runner that takes the OtOpcUaConfig database from the v1 schema
    (with ConfigGeneration / ClusterNodeGenerationState) to the v2 hosting-aligned schema
    (with Deployment / NodeDeploymentState / ConfigEdit / DataProtectionKeys).

.DESCRIPTION
    Backs the database up, applies the idempotent EF migration script, then validates that
    expected tables exist and legacy tables are gone. Safe to re-run — the EF script itself
    is idempotent, and the backup picks a unique filename per invocation.

.PARAMETER ConnectionString
    Mandatory. Full ADO.NET connection string with permissions to BACKUP DATABASE and
    apply DDL on the target ConfigDb.

.PARAMETER BackupPath
    Optional. Full path for the backup file. Defaults to a timestamped path under $env:TEMP.

.EXAMPLE
    .\Migrate-To-V2.ps1 -ConnectionString "Server=sql01;Database=OtOpcUaConfig;Trusted_Connection=True;TrustServerCertificate=True"
#>
[CmdletBinding()]
param(
    [Parameter(Mandatory)][string] $ConnectionString,
    [string] $BackupPath = "$env:TEMP\OtOpcUa-V1-Backup-$(Get-Date -Format yyyyMMddHHmmss).bak"
)

$ErrorActionPreference = 'Stop'

if (-not (Get-Command Invoke-Sqlcmd -ErrorAction SilentlyContinue)) {
    throw "Invoke-Sqlcmd not available. Install module: Install-Module SqlServer -Scope CurrentUser"
}

Write-Host "Step 1/4 — Backup ConfigDb to $BackupPath" -ForegroundColor Cyan
Invoke-Sqlcmd -ConnectionString $ConnectionString `
    -Query "BACKUP DATABASE [OtOpcUaConfig] TO DISK = '$BackupPath' WITH FORMAT, COMPRESSION"

Write-Host "Step 2/4 — Row counts (before)" -ForegroundColor Cyan
$beforeCounts = Invoke-Sqlcmd -ConnectionString $ConnectionString -InputFile "$PSScriptRoot\count-rows.sql"
$beforeCounts | Format-Table

Write-Host "Step 3/4 — Apply Migrate-To-V2.sql" -ForegroundColor Cyan
Invoke-Sqlcmd -ConnectionString $ConnectionString -InputFile "$PSScriptRoot\Migrate-To-V2.sql" -QueryTimeout 1800

Write-Host "Step 4/4 — Row counts (after) + validation" -ForegroundColor Cyan
$afterCounts = Invoke-Sqlcmd -ConnectionString $ConnectionString -InputFile "$PSScriptRoot\count-rows.sql"
$afterCounts | Format-Table

$tablesNow = (Invoke-Sqlcmd -ConnectionString $ConnectionString `
    -Query "SELECT name FROM sys.tables ORDER BY name").name

foreach ($t in 'Deployment','NodeDeploymentState','ConfigEdit','DataProtectionKeys') {
    if ($tablesNow -notcontains $t) { throw "Expected v2 table $t missing." }
}
foreach ($t in 'ConfigGeneration','ClusterNodeGenerationState') {
    if ($tablesNow -contains $t) { throw "Legacy v1 table $t still present." }
}

Write-Host "Migration complete. Backup at $BackupPath" -ForegroundColor Green
