param(
  [string]$ProjectRoot = "",
  [switch]$AsJson
)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

if ([string]::IsNullOrWhiteSpace($ProjectRoot)) {
  $ProjectRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot "..\..\..\.."))
}

function New-Issue {
  param(
    [string]$Severity,
    [string]$File,
    [string]$Section,
    [string]$Message
  )

  [PSCustomObject]@{
    severity = $Severity
    file = $File
    section = $Section
    message = $Message
  }
}

function Get-FileContentOrNull {
  param([string]$Path)

  if (-not (Test-Path -LiteralPath $Path)) {
    return $null
  }

  Get-Content -LiteralPath $Path -Raw
}

function Resolve-FirstExistingPath {
  param([string[]]$Candidates)

  foreach ($candidate in $Candidates) {
    if (Test-Path -LiteralPath $candidate) {
      return $candidate
    }
  }

  return $null
}

function Test-ContainsAll {
  param(
    [string]$Content,
    [string[]]$Terms
  )

  foreach ($term in $Terms) {
    if ($Content -notmatch [regex]::Escape($term)) {
      return $false
    }
  }

  return $true
}

$issues = @()

$featureTemplatePath = Join-Path $ProjectRoot "tools\harness\templates\feature-task-reference.json"
$implementPromptPath = Join-Path $ProjectRoot ".codex\prompts\implement-one-task.md"
$stage2PromptPath = Join-Path $ProjectRoot ".codex\prompts\review-stage2-quality.md"
$verifyMatrixPath = Resolve-FirstExistingPath -Candidates @(
  (Join-Path $ProjectRoot "docs\testing\verify-matrix.md"),
  (Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\testing\verify-matrix.md")
)

$featureTemplate = Get-FileContentOrNull -Path $featureTemplatePath
if ($null -eq $featureTemplate) {
  $issues += New-Issue -Severity "error" -File "tools/harness/templates/feature-task-reference.json" -Section "file" -Message "缺少 feature-task-reference，无法约束 acceptance 和 qa_contract。"
}
elseif (-not (Test-ContainsAll -Content $featureTemplate -Terms @('"acceptance"', '"qa_contract"', '"positive_cases"', '"negative_cases"', '"boundary_cases"', '"regression_cases"', '"risk_checks"', '"blocked_if_missing"', '"acceptance_test_matrix"'))) {
  $issues += New-Issue -Severity "error" -File "tools/harness/templates/feature-task-reference.json" -Section "qa-contract" -Message "feature-task-reference 缺少 acceptance 或 qa_contract 验收分组字段。"
}

$implementPrompt = Get-FileContentOrNull -Path $implementPromptPath
if ($null -eq $implementPrompt) {
  $issues += New-Issue -Severity "error" -File ".codex/prompts/implement-one-task.md" -Section "file" -Message "缺少 implement prompt。"
}
elseif (-not (Test-ContainsAll -Content $implementPrompt -Terms @("acceptance 到验证动作的映射", "acceptance 必须至少映射到一个实现入口", "positive_cases", "negative_cases", "boundary_cases", "regression_cases", "输出 BLOCKED"))) {
  $issues += New-Issue -Severity "error" -File ".codex/prompts/implement-one-task.md" -Section "acceptance-mapping" -Message "implement prompt 没有把 acceptance 映射和 qa_contract case 分组变成阻塞条件。"
}

$stage2Prompt = Get-FileContentOrNull -Path $stage2PromptPath
if ($null -eq $stage2Prompt) {
  $issues += New-Issue -Severity "error" -File ".codex/prompts/review-stage2-quality.md" -Section "file" -Message "缺少 Stage 2 review prompt。"
}
elseif (-not (Test-ContainsAll -Content $stage2Prompt -Terms @("acceptance 到验证动作的显式映射", "positive_cases", "negative_cases", "boundary_cases", "regression_cases", '必须 `FAIL`'))) {
  $issues += New-Issue -Severity "error" -File ".codex/prompts/review-stage2-quality.md" -Section "acceptance-review" -Message "Stage 2 prompt 缺少 acceptance 映射拒绝规则或四类 case 检查。"
}

$verifyMatrix = Get-FileContentOrNull -Path $verifyMatrixPath
if ($null -eq $verifyMatrix) {
  $issues += New-Issue -Severity "error" -File "docs/testing/verify-matrix.md" -Section "file" -Message "缺少 verify-matrix，无法承接 acceptance 到验证动作的矩阵。"
}
elseif (-not (Test-ContainsAll -Content $verifyMatrix -Terms @("验收 / 示例", "用户验收链路", "失败态验收", "发布候选验证"))) {
  $issues += New-Issue -Severity "error" -File "docs/testing/verify-matrix.md" -Section "matrix" -Message "verify-matrix 缺少 acceptance-to-test 必需行。"
}

$errors = @($issues | Where-Object { $_.severity -eq "error" })
$warnings = @($issues | Where-Object { $_.severity -eq "warning" })
$exitCode = if ($errors.Count -gt 0) { 1 } elseif ($warnings.Count -gt 0) { 2 } else { 0 }

if ($AsJson) {
  [PSCustomObject]@{
    ok = ($exitCode -eq 0)
    errors = $errors
    warnings = $warnings
  } | ConvertTo-Json -Depth 6
  exit $exitCode
}

if ($errors.Count -eq 0 -and $warnings.Count -eq 0) {
  Write-Output "Acceptance contract lint passed."
  exit 0
}

if ($errors.Count -gt 0) {
  Write-Output "Acceptance contract lint failed."
  foreach ($issue in $errors) {
    Write-Output ("- [ERROR] {0} :: {1} :: {2}" -f $issue.file, $issue.section, $issue.message)
  }
}

if ($warnings.Count -gt 0) {
  if ($errors.Count -eq 0) {
    Write-Output "Acceptance contract lint passed with warnings."
  }
  foreach ($issue in $warnings) {
    Write-Output ("- [WARNING] {0} :: {1} :: {2}" -f $issue.file, $issue.section, $issue.message)
  }
}

exit $exitCode
