# Resolve ctl.Servers -> live collection targets (data-driven resolver)
. (Join-Path $PSScriptRoot 'SovereignEnv.ps1')

function Invoke-SovereignRepositoryQuery {
    param(
        [string]$ConnectionString,
        [string]$Query,
        [hashtable]$Parameters = @{}
    )
    Add-Type -AssemblyName 'System.Data' -ErrorAction SilentlyContinue
    $conn = New-Object System.Data.SqlClient.SqlConnection $ConnectionString
    $conn.Open()
    try {
    try {
        $cmd = $conn.CreateCommand()
        $cmd.CommandText = $Query
        foreach ($k in $Parameters.Keys) {
            $val = $Parameters[$k]
            if ($k -eq 'sid' -and $null -ne $val -and $val -ne '') {
                $p = $cmd.Parameters.Add('@sid', [System.Data.SqlDbType]::UniqueIdentifier)
                $p.Value = [guid]$val
            } elseif ($k -eq 'inc') {
                $p = $cmd.Parameters.Add('@inc', [System.Data.SqlDbType]::Bit)
                $p.Value = [bool]([int]$val)
            } else {
                $p = $cmd.Parameters.Add("@$k", [System.Data.SqlDbType]::NVarChar, 4000)
                if ($null -eq $val) { $p.Value = [DBNull]::Value } else { $p.Value = $val }
            }
        }
        $adapter = New-Object System.Data.SqlClient.SqlDataAdapter $cmd
        $dt = New-Object System.Data.DataTable
        [void]$adapter.Fill($dt)
        return $dt
    } finally {
        $conn.Close()
    }
}

function Get-SovereignCollectionTargetsFromApi {
    param(
        [string]$SovereignApi = 'http://localhost:3041',
        [string]$ServerId,
        [switch]$IncludeIneligible
    )
    $uri = "$($SovereignApi.TrimEnd('/'))/api/fleet/collection-targets"
    if ($ServerId) { $uri += "?serverId=$ServerId" }
    elseif ($IncludeIneligible) { $uri += '?includeIneligible=true' }
    $resp = Invoke-RestMethod -Uri $uri -TimeoutSec 30
    return @($resp.targets)
}

function Get-SovereignCollectionTargetsFromSql {
    param(
        [string]$RepositoryConnection,
        [string]$ServerId,
        [switch]$IncludeIneligible
    )
    $cs = Get-SovereignRepositoryConnectionString -Override $RepositoryConnection
    if (-not $cs) { throw 'SOVEREIGN_DB_CONNECTION not set and -RepositoryConnection not provided.' }

    $dt = $null
    try {
        $dt = Invoke-SovereignRepositoryQuery -ConnectionString $cs -Query 'EXEC ctl.usp_ResolveCollectionTargets @sid, @inc' -Parameters @{
            sid = $(if ($ServerId) { $ServerId } else { $null })
            inc = $(if ($IncludeIneligible) { 1 } else { 0 })
        }
    } catch {
        Write-Warning "usp_ResolveCollectionTargets unavailable — using ctl.Servers fallback ($($_.Exception.Message))"
        $where = 'WHERE IsActive = 1'
        if ($ServerId) { $where += ' AND ServerId = @sid' }
        $dt = Invoke-SovereignRepositoryQuery -ConnectionString $cs -Query @"
SELECT ServerId, ServerName, Engine, Environment, Port, AuthMode, CredentialRef,
       ConnectOverride, IsActive, CollectionEligible
FROM ctl.Servers $where ORDER BY ServerName
"@ -Parameters $(if ($ServerId) { @{ sid = $ServerId } } else { @{} })
    }

    $targets = @()
    foreach ($r in $dt.Rows) {
        $hasView = $dt.Columns.Contains('ConnectName')
        if ($hasView -and $r.ConnectName -isnot [DBNull] -and [string]$r.ConnectName) {
            $connect = [string]$r.ConnectName
        } else {
            $override = if ($r.ConnectOverride -is [DBNull]) { $null } else { [string]$r.ConnectOverride }
            $connect = if ($override) { $override.Trim() }
            elseif ($r.Port -isnot [DBNull] -and [int]$r.Port -gt 0 -and -not [string]$r.ServerName.Contains('\')) {
                "$($r.ServerName),$($r.Port)"
            } else { [string]$r.ServerName }
        }

        $engine = [string]$r.Engine
        if ($dt.Columns.Contains('IsCollectable') -and $r.IsCollectable -isnot [DBNull]) {
            $collectable = [bool]($r.IsCollectable -eq $true -or [int]$r.IsCollectable -eq 1)
        } else {
            $override = if ($r.ConnectOverride -is [DBNull]) { $null } else { [string]$r.ConnectOverride }
            $eligible = ($r.CollectionEligible -eq $true -or [int]$r.CollectionEligible -eq 1)
            $active = ($r.IsActive -eq $true -or [int]$r.IsActive -eq 1)
            $collectable = $active -and $eligible -and (
                $engine -in @('SQL Server', 'Azure SQL') -or ($override -and $override.Trim())
            )
        }

        if (-not $IncludeIneligible -and -not $collectable) { continue }

        $targets += [pscustomobject]@{
            serverId      = [string]$r.ServerId
            serverName    = [string]$r.ServerName
            connectName   = $connect
            engine        = $engine
            environment   = if ($r.Environment -is [DBNull]) { $null } else { [string]$r.Environment }
            port          = if ($r.Port -is [DBNull]) { $null } else { [int]$r.Port }
            authMode      = if ($r.AuthMode -is [DBNull]) { 'Integrated' } else { [string]$r.AuthMode }
            credentialRef = if ($r.CredentialRef -is [DBNull]) { $null } else { [string]$r.CredentialRef }
            isCollectable = [bool]$collectable
        }
    }
    return $targets
}

function Get-SovereignCollectionTargets {
    param(
        [string]$SovereignApi = 'http://localhost:3041',
        [string]$RepositoryConnection,
        [ValidateSet('Api', 'Sql', 'Auto')]
        [string]$Source = 'Auto',
        [string]$ServerId,
        [switch]$IncludeIneligible
    )

    if ($Source -eq 'Api' -or ($Source -eq 'Auto' -and -not (Get-SovereignRepositoryConnectionString -Override $RepositoryConnection))) {
        try {
            return Get-SovereignCollectionTargetsFromApi -SovereignApi $SovereignApi -ServerId $ServerId -IncludeIneligible:$IncludeIneligible
        } catch {
            if ($Source -eq 'Api') { throw }
        }
    }
    return Get-SovereignCollectionTargetsFromSql -RepositoryConnection $RepositoryConnection -ServerId $ServerId -IncludeIneligible:$IncludeIneligible
}
