///|
/// A route's observed response and the result of checking its capability contract.
pub struct CapabilityResponseAudit {
  sample : ResponseSample
  report : CapabilityContractReport
} derive(Eq, @debug.Debug)

///|
/// Audit the actual response headers for one declared route.
///
/// This check requires a modern Permissions-Policy header. Legacy Feature-Policy
/// can still be inspected with audit_header_block for migration work.
pub fn audit_capability_response(
  sample : ResponseSample,
  contract : CapabilityContract,
) -> CapabilityResponseAudit {
  let headers = parse_header_block(sample.header_block)
  let policy = policy_from_headers(headers)
  let base = audit_capability_contract(policy, contract)
  let findings : Array[CapabilityFinding] = []
  let mut invalid_response = false
  if permissions_policy_header(headers) is None {
    invalid_response = true
    findings.push({
      severity: SeverityHigh,
      code: "permissions-policy-header-missing",
      feature: "-",
      target_origin: "-",
      message: "response does not contain a modern Permissions-Policy header",
    })
  }
  if policy.warnings.length() > 0 {
    invalid_response = true
    findings.push({
      severity: SeverityHigh,
      code: "response-policy-invalid",
      feature: "-",
      target_origin: "-",
      message: "response header block or capability policy has parse warnings",
    })
  }
  if normalize_origin(sample.document_origin) != base.contract.document_origin {
    invalid_response = true
    findings.push({
      severity: SeverityHigh,
      code: "document-origin-mismatch",
      feature: "-",
      target_origin: normalize_origin(sample.document_origin),
      message: "response origin differs from the declared contract origin",
    })
  }
  for finding in base.findings {
    if finding.code != "capability-contract-satisfied" || !invalid_response {
      findings.push(finding)
    }
  }
  { sample, report: { ..base, ok: base.ok && !invalid_response, findings, }, }
}

///|
/// Render a route-level response audit for CI logs.
pub fn render_capability_response_audit(
  audit : CapabilityResponseAudit,
) -> String {
  "route=" +
  audit.sample.path +
  " sample=" +
  audit.sample.name +
  "\n" +
  render_capability_contract_report(audit.report)
}