# ArcIn Connector Agent - MySQL data source configurator
#
# Run from Administrator PowerShell:
#   powershell -ExecutionPolicy Bypass -File .\configure-mysql.ps1 `
#       -SourceId    "mysql-prod" `
#       -MySqlHost   "your-mysql-host" `
#       -MySqlPort   3306 `
#       -MySqlUser   "readonlyuser" `
#       -MySqlPass   "password" `
#       -MySqlDb     "your-database"

[CmdletBinding()]
param(
    [Parameter(Mandatory)][string]$MySqlHost,
    [Parameter(Mandatory)][string]$MySqlUser,
    [Parameter(Mandatory)][string]$MySqlPass,
    [Parameter(Mandatory)][string]$MySqlDb,
    [int]   $MySqlPort = 3306,
    [string]$SourceId  = "mysql-prod"
)

$ErrorActionPreference = 'Stop'

$ConfigFile  = "C:\ProgramData\ArcInAgent\agent.yaml"
$ServiceName = "ArcInAgent"
$EnvVarName  = "ARCIN_SOURCE_$($SourceId.ToUpper() -replace '[^A-Z0-9]','_')_DSN"

# ── Admin check ────────────────────────────────────────────────────────────────
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
if (-not (New-Object Security.Principal.WindowsPrincipal($id)).IsInRole(
        [Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Error "Must run as Administrator."; exit 1
}

# ── Reset ACL so we can read/write the config ──────────────────────────────────
& takeown /F $ConfigFile /A /D Y 2>&1 | Out-Null
& icacls  $ConfigFile /grant "BUILTIN\Administrators:F" /C /Q 2>&1 | Out-Null

# ── 1. Set DSN as Machine-level environment variable ──────────────────────────
Write-Host "[1] Setting environment variable: $EnvVarName" -ForegroundColor Cyan
$dsn = "${MySqlUser}:${MySqlPass}@tcp(${MySqlHost}:${MySqlPort})/${MySqlDb}"
[System.Environment]::SetEnvironmentVariable($EnvVarName, $dsn, "Machine")
Write-Host "    DSN: ${MySqlUser}:***@tcp(${MySqlHost}:${MySqlPort})/${MySqlDb}"
Write-Host "    OK" -ForegroundColor Green

# ── 2. Update agent.yaml sources block ────────────────────────────────────────
Write-Host "[2] Updating $ConfigFile" -ForegroundColor Cyan
$content = Get-Content $ConfigFile -Raw

$newSource = @"
sources:
  - id: "$SourceId"
    type: "mysql"
    dsn_env_var: "$EnvVarName"
    role: "readonly"
"@

# Replace 'sources: []' or existing sources block
if ($content -match '(?s)sources:.*?(?=\n\S|\Z)') {
    $content = $content -replace '(?s)(sources:\s*\[\])', $newSource
    # If already had entries, check if this source id already exists
    if ($content -match "id:\s*`"$SourceId`"") {
        Write-Host "    Source '$SourceId' already exists - skipping yaml update." -ForegroundColor Yellow
    } elseif ($content -notmatch 'dsn_env_var') {
        # sources: [] was replaced
        Write-Host "    Added source '$SourceId'." -ForegroundColor Green
    }
}
Set-Content -Path $ConfigFile -Value $content -Encoding UTF8
Write-Host "    OK" -ForegroundColor Green

# ── 3. Re-harden the ACL ──────────────────────────────────────────────────────
Write-Host "[3] Re-hardening ACL on config file" -ForegroundColor Cyan
$acl = Get-Acl $ConfigFile
$acl.SetAccessRuleProtection($true, $false)
foreach ($r in @($acl.Access)) { [void]$acl.RemoveAccessRule($r) }
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule `
    -ArgumentList 'NT AUTHORITY\SYSTEM',    'FullControl', 'Allow'))
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule `
    -ArgumentList 'BUILTIN\Administrators', 'FullControl', 'Allow'))
Set-Acl -Path $ConfigFile -AclObject $acl
Write-Host "    OK" -ForegroundColor Green

# ── 4. Restart service ────────────────────────────────────────────────────────
Write-Host "[4] Restarting $ServiceName..." -ForegroundColor Cyan
Restart-Service $ServiceName
Start-Sleep -Seconds 5
$status = (Get-Service $ServiceName).Status
Write-Host "    Service status: $status" -ForegroundColor $(if ($status -eq 'Running') { 'Green' } else { 'Red' })

# ── 5. Check logs for source registration ─────────────────────────────────────
Write-Host "[5] Checking agent log..." -ForegroundColor Cyan
$logFile = "C:\ProgramData\ArcInAgent\logs\agent.log"
Start-Sleep -Seconds 3
if (Test-Path $logFile) {
    $lines = Get-Content $logFile | Select-Object -Last 30
    $lines | ForEach-Object {
        try {
            $j = $_ | ConvertFrom-Json
            $color = switch ($j.level) { 'INFO'{'Green'} 'WARN'{'Yellow'} 'ERROR'{'Red'} default{'White'} }
            Write-Host "    [$($j.level)] $($j.msg)$(if($j.id){" id=$($j.id)"})" -ForegroundColor $color
        } catch { Write-Host "    $_" }
    }
} else {
    Write-Host "    Log file not found yet." -ForegroundColor Yellow
}

Write-Host ""
if ($status -eq 'Running') {
    Write-Host "Done. Source '$SourceId' configured." -ForegroundColor Green
    Write-Host "Logs: $logFile"
}
