/**
 * T11 — v0.9 MINIMAL deprovision (self-contained; superseded by T13 fast path in v0.10). Requires
 * `ownsHost(principal.accountId, hostId)` (INV1/INV6), then `setHostStatus('revoked')` (T4 versioned
 * snapshot) + `dropRoute` (T9). Best-effort tunnel drop only — NOT the INV12 within-seconds
 * guarantee (that is T13's `revokeHost`). Depends on T4 + T9 ONLY; no dependency on v0.10.
 */
import type { HostRegistry } from '../registry/hosts.js'
import type { RoutingTable } from '../routing/table.js'
import type { AdminPrincipal } from '../api/authz.js'
import { AuthzError } from '../api/authz.js'

export interface Deprovisioner {
  deprovisionHost(principal: AdminPrincipal, hostId: string): Promise<void>
}

export interface DeprovisionDeps {
  readonly hosts: HostRegistry
  readonly routing: RoutingTable
}

export function createDeprovisioner(deps: DeprovisionDeps): Deprovisioner {
  return {
    async deprovisionHost(principal, hostId) {
      if (!(await deps.hosts.ownsHost(principal.accountId, hostId))) {
        throw new AuthzError(403, 'not authorized for this host') // INV1: 403, never a 404 leak
      }
      const host = await deps.hosts.getHost(hostId)
      if (host !== null && host.status !== 'revoked') {
        await deps.hosts.setHostStatus(hostId, 'revoked')
      }
      await deps.routing.systemDropRoute(hostId)
    },
  }
}
