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

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 Test-ContainsAll {
  param(
    [string]$Content,
    [string[]]$Terms
  )

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

  return $true
}

$issues = @()

$prdPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\product\prd-lite.md"
$stateMatrixPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\product\state-matrix.yaml"
$traceabilityPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\testing\TRACEABILITY_MATRIX.md"
$testStrategyPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\testing\TEST_STRATEGY.md"
$nlCasesPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\testing\NATURAL_LANGUAGE_TEST_CASES.md"

$prd = Get-FileContentOrNull -Path $prdPath
$stateMatrix = Get-FileContentOrNull -Path $stateMatrixPath
$traceability = Get-FileContentOrNull -Path $traceabilityPath
$testStrategy = Get-FileContentOrNull -Path $testStrategyPath
$nlCases = Get-FileContentOrNull -Path $nlCasesPath

if ($null -eq $prd) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/product/prd-lite.md" -Section "file" -Message "缺少 PRD-Lite 模板，无法承载业务规则。"
}
else {
  if (-not (Test-ContainsAll -Content $prd -Terms @("## 11. 业务规则", "状态流转规则", "权限拒绝规则", "幂等 / 重复提交规则", "外部依赖失败或超时后的兜底规则", "关键不变量"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/product/prd-lite.md" -Section "business-rules" -Message "PRD-Lite 模板缺少第七章要求的业务规则类型清单。"
  }
}

if ($null -eq $stateMatrix) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/product/state-matrix.yaml" -Section "file" -Message "缺少状态矩阵模板。"
}
else {
  if (-not (Test-ContainsAll -Content $stateMatrix -Terms @("related_business_rules", "business_rule_checklist", "是否存在重复提交 / 幂等保护", "是否存在关键不变量"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/product/state-matrix.yaml" -Section "rule-binding" -Message "状态矩阵模板缺少业务规则绑定或关键规则检查清单。"
  }
}

if ($null -eq $traceability) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/testing/TRACEABILITY_MATRIX.md" -Section "file" -Message "缺少追溯矩阵模板。"
}
else {
  if (-not (Test-ContainsAll -Content $traceability -Terms @("业务规则", "每条 P0/P1 业务规则至少要在矩阵中出现一次", "写操作、权限失败、非法状态流转和异步链路必须包含副作用或无副作用 Oracle"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/testing/TRACEABILITY_MATRIX.md" -Section "traceability-rules" -Message "追溯矩阵模板缺少业务规则追溯或异常路径 Oracle 约束。"
  }
}

if ($null -eq $testStrategy) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/testing/TEST_STRATEGY.md" -Section "file" -Message "缺少测试策略模板。"
}
else {
  if (-not (Test-ContainsAll -Content $testStrategy -Terms @("不能只写 happy path", "业务规则如果会影响状态流转、副作用、金额/库存、权限或幂等，必须至少有一条异常路径或无副作用路径用例"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/testing/TEST_STRATEGY.md" -Section "business-coverage" -Message "测试策略模板缺少第七章要求的非 happy path 业务规则覆盖约束。"
  }
}

if ($null -eq $nlCases) {
  $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/testing/NATURAL_LANGUAGE_TEST_CASES.md" -Section "file" -Message "缺少自然语言测试用例模板。"
}
else {
  if (-not (Test-ContainsAll -Content $nlCases -Terms @("重放请求", "无副作用证据", "不能只挂在 PRD 文本里不进测试"))) {
    $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/testing/NATURAL_LANGUAGE_TEST_CASES.md" -Section "business-rule-cases" -Message "自然语言用例模板还没有明确高风险业务规则必须映射测试用例。"
  }
}

$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 -and -not $AllowWarningsOnly) { 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 "Business lint passed."
  exit 0
}

if ($errors.Count -gt 0) {
  Write-Output "Business 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 "Business lint passed with warnings."
  }
  foreach ($issue in $warnings) {
    Write-Output ("- [WARNING] {0} :: {1} :: {2}" -f $issue.file, $issue.section, $issue.message)
  }
}

exit $exitCode
