/**
 * get-dhcp-scopes — list DHCP scopes + lease statistics + reservations.
 * Site-anchored. Useful for documenting subnet plans + finding stale
 * reservations that should be retired.
 */

import { type RmmScript, parseJsonOutput } from './types';

export const getDhcpScopes: RmmScript = {
  id: 'get-dhcp-scopes',
  name: 'DHCP scopes + reservations',
  description:
    'All authorized DHCP servers in the domain, their scopes, scope-level statistics, and reservations.',
  target_type: 'site_anchor',
  expected_runtime_seconds: 60,
  version: 1,
  body: `
$ErrorActionPreference = 'SilentlyContinue'
Import-Module DhcpServer -ErrorAction SilentlyContinue

$servers = Get-DhcpServerInDC -ErrorAction SilentlyContinue

$result = foreach ($srv in $servers) {
  $scopes = Get-DhcpServerv4Scope -ComputerName $srv.DnsName -ErrorAction SilentlyContinue
  $detail = foreach ($sc in $scopes) {
    $stats = Get-DhcpServerv4ScopeStatistics -ComputerName $srv.DnsName -ScopeId $sc.ScopeId -ErrorAction SilentlyContinue
    $resv = Get-DhcpServerv4Reservation -ComputerName $srv.DnsName -ScopeId $sc.ScopeId -ErrorAction SilentlyContinue |
      Select-Object IPAddress, ClientId, Description, Name
    [pscustomobject]@{
      scope_id     = $sc.ScopeId.ToString()
      name         = $sc.Name
      subnet_mask  = $sc.SubnetMask.ToString()
      start_range  = $sc.StartRange.ToString()
      end_range    = $sc.EndRange.ToString()
      state        = $sc.State.ToString()
      lease_duration_hours = $sc.LeaseDuration.TotalHours
      addresses_in_use = if ($stats) { $stats.InUse } else { $null }
      addresses_free   = if ($stats) { $stats.Free } else { $null }
      percentage_in_use = if ($stats) { $stats.PercentageInUse } else { $null }
      reservations = $resv
    }
  }
  [pscustomobject]@{
    dhcp_server = $srv.DnsName
    ip = $srv.IPAddress.ToString()
    scopes = $detail
  }
}

@{
  hostname = $env:COMPUTERNAME
  captured_at_utc = (Get-Date).ToUniversalTime().ToString("o")
  servers = $result
} | ConvertTo-Json -Depth 6 -Compress
`.trim(),
  parseOutput: (stdout) => parseJsonOutput(stdout),
};
