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 = @()

$codeNavPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\docs\code-semantics-and-navigation.md"
$repoMapPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\context\repo-map.md"
$currentTaskPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\context\CURRENT_TASK.md"
$devPlanPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\context\dev-plan.md"
$regressionPlanPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\testing\REGRESSION_PLAN.md"
$implementPromptPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\prompts\implement-one-task.md"
$featureTaskTemplatePath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\runtime\feature-task-reference.json"
$taskSchemaPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\runtime\task.schema.json"
$traceSchemaPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\trace\trace.schema.json"

$codeNav = Get-FileContentOrNull -Path $codeNavPath
$repoMap = Get-FileContentOrNull -Path $repoMapPath
$currentTask = Get-FileContentOrNull -Path $currentTaskPath
$devPlan = Get-FileContentOrNull -Path $devPlanPath
$regressionPlan = Get-FileContentOrNull -Path $regressionPlanPath
$implementPrompt = Get-FileContentOrNull -Path $implementPromptPath
$featureTaskTemplate = Get-FileContentOrNull -Path $featureTaskTemplatePath
$taskSchema = Get-FileContentOrNull -Path $taskSchemaPath
$traceSchema = Get-FileContentOrNull -Path $traceSchemaPath

if ($null -eq $codeNav) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/docs/code-semantics-and-navigation.md" -Section "file" -Message "缺少代码语义与导航模板。"
}
else {
  if (-not (Test-ContainsAll -Content $codeNav -Terms @("影响面分析最少回答", "入口在哪里", "上游是谁", "下游是谁", "受影响文件有哪些", "受影响测试和验证命令有哪些"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/docs/code-semantics-and-navigation.md" -Section "impact-baseline" -Message "代码语义与导航模板缺少第14章要求的调用链和影响面最小回答。"
  }
}

if ($null -eq $repoMap) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/context/repo-map.md" -Section "file" -Message "缺少 repo-map 模板。"
}
else {
  if (-not (Test-ContainsAll -Content $repoMap -Terms @("关键调用链", "影响面分析时至少回答", "受影响文件有哪些", "受影响测试和验证命令有哪些"))) {
    $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/context/repo-map.md" -Section "impact-entry" -Message "repo-map 模板还没有完整承接第14章的影响面分析入口。"
  }
}

if ($null -eq $currentTask) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/context/CURRENT_TASK.md" -Section "file" -Message "缺少 CURRENT_TASK 模板。"
}
else {
  if (-not (Test-ContainsAll -Content $currentTask -Terms @("可能影响哪些调用方", "直接影响", "间接影响", "相关接口 / 契约", "相关页面 / 路由", "回归范围"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/context/CURRENT_TASK.md" -Section "impact-fields" -Message "CURRENT_TASK 模板缺少第14章要求的影响面字段。"
  }
}

if ($null -eq $devPlan) {
  $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/context/dev-plan.md" -Section "file" -Message "缺少 DEV-PLAN 模板。"
}
else {
  if (-not (Test-ContainsAll -Content $devPlan -Terms @("affected tests", "evidence path 和回归范围", "P0/P1 需求缺少 `TEST_DATA_MATRIX.md`、`REGRESSION_PLAN.md` 或 affected tests"))) {
    $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/context/dev-plan.md" -Section "impact-plan" -Message "DEV-PLAN 模板还没有完整承接第14章要求的 affected tests 和回归范围约束。"
  }
}

if ($null -eq $regressionPlan) {
  $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/testing/REGRESSION_PLAN.md" -Section "file" -Message "缺少回归计划模板。"
}
else {
  if (-not (Test-ContainsAll -Content $regressionPlan -Terms @("## 影响面", "直接影响", "间接影响", "相关接口 / 契约", "相关页面 / 路由", "潜在风险"))) {
    $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/testing/REGRESSION_PLAN.md" -Section "impact-regression" -Message "回归计划模板还没有完整承接第14章要求的影响面与回归范围字段。"
  }
}

if ($null -eq $implementPrompt) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/prompts/implement-one-task.md" -Section "file" -Message "缺少 implement-one-task prompt。"
}
else {
  if (-not (Test-ContainsAll -Content $implementPrompt -Terms @("### Phase 3: Impact Analysis", "relevant_files", "call_chain", "data_flow", "state_flow", "affected_apis", "affected_ui_user_paths", "affected_tests", "compatibility", "security", "performance", "concurrency", "migration", "rollback", "owned_paths"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/prompts/implement-one-task.md" -Section "impact-prompt" -Message "implement prompt 缺少完整的影响面分析阶段或关键维度。"
  }
}

if ($null -eq $featureTaskTemplate) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/runtime/feature-task-reference.json" -Section "file" -Message "缺少 feature task reference 模板。"
}
else {
  if (-not (Test-ContainsAll -Content $featureTaskTemplate -Terms @('"impact_analysis_required"', '"impact_analysis_summary"', '"relevant_files"', '"call_chain"', '"data_flow"', '"state_flow"', '"affected_apis"', '"affected_ui_user_paths"', '"affected_tests"', '"compatibility_risks"', '"security_permission_risks"', '"performance_risks"', '"concurrency_transaction_risks"', '"migration_risks"', '"rollback_considerations"', '"owned_paths_coverage"'))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/runtime/feature-task-reference.json" -Section "impact-contract" -Message "feature task reference 缺少结构化影响面字段。"
  }
}

if ($null -eq $taskSchema) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/runtime/task.schema.json" -Section "file" -Message "缺少 task schema。"
}
else {
  if (-not (Test-ContainsAll -Content $taskSchema -Terms @('"impact_analysis_required"', '"impact_analysis_summary"', '"relevant_files"', '"call_chain"', '"data_flow"', '"state_flow"', '"affected_apis"', '"affected_ui_user_paths"', '"affected_tests"', '"compatibility_risks"', '"security_permission_risks"', '"performance_risks"', '"concurrency_transaction_risks"', '"migration_risks"', '"rollback_considerations"', '"owned_paths_coverage"'))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/runtime/task.schema.json" -Section "impact-schema" -Message "task schema 缺少影响面分析字段约束。"
  }
}

if ($null -eq $traceSchema) {
  $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/trace/trace.schema.json" -Section "file" -Message "缺少 trace schema。"
}
else {
  if (-not (Test-ContainsAll -Content $traceSchema -Terms @('"impact_analysis_summary"', '"relevant_files"', '"call_chain"', '"data_flow"', '"state_flow"', '"affected_apis"', '"affected_ui_user_paths"', '"affected_tests"', '"compatibility_risks"', '"security_permission_risks"', '"performance_risks"', '"concurrency_transaction_risks"', '"migration_risks"', '"rollback_considerations"', '"owned_paths_coverage"'))) {
    $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/trace/trace.schema.json" -Section "impact-trace" -Message "trace schema 还没有完整记录结构化影响面分析。"
  }
}

$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 "Impact lint passed."
  exit 0
}

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

exit $exitCode
