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-ContainsPlaceholder {
  param([string]$Content)

  if ([string]::IsNullOrWhiteSpace($Content)) {
    return $false
  }

  return (
    $Content -match '(?im)\bTBD\b' -or
    $Content -match '(?im)\bTODO\b' -or
    $Content -match '(?im)<replace-' -or
    $Content -match '(?im)REQ-REPLACE|FR-REPLACE|NFR-REPLACE|META-HANDOFF-REPLACE'
  )
}

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

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

  return $true
}

$issues = @()

$architectureRulesPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\docs\project-agents-template.md"
$currentTaskPath = Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\context\CURRENT_TASK.md"
$taskTemplatePath = Join-Path $ProjectRoot "tools\harness\templates\project-task-template.json"
$featureTaskReferencePath = Join-Path $ProjectRoot "tools\harness\templates\feature-task-reference.json"

$architectureRules = Get-FileContentOrNull -Path $architectureRulesPath
$currentTask = Get-FileContentOrNull -Path $currentTaskPath
$taskTemplate = Get-FileContentOrNull -Path $taskTemplatePath
$featureTaskReference = Get-FileContentOrNull -Path $featureTaskReferencePath

if ($null -eq $architectureRules) {
  $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/docs/project-agents-template.md" -Section "file" -Message "缺少 project AGENTS 模板，无法承载第三章目录级架构规则。"
}
else {
  if (-not (Test-ContainsAll -Content $architectureRules -Terms @("全项目都成立的入口规则", "子目录", "本目录负责什么", "本目录不负责什么", "决策表"))) {
    $issues += New-Issue -Severity "error" -File "docs/codex-harness-engineering/templates/docs/project-agents-template.md" -Section "local-agents-architecture" -Message "project AGENTS 模板缺少目录级架构规则承载结构。"
  }
  if (-not (Test-ContainsAll -Content $architectureRules -Terms @("repository/service", "不要跨层调用"))) {
    $issues += New-Issue -Severity "warning" -File "docs/codex-harness-engineering/templates/docs/project-agents-template.md" -Section "layering-sample" -Message "project AGENTS 模板还缺少更具体的分层规则样板。"
  }
}

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 "reuse-check-fields" -Message "CURRENT_TASK 模板缺少第三章要求的模块归属和类似实现检查字段。"
  }
}

if ($null -eq $taskTemplate) {
  $issues += New-Issue -Severity "error" -File "tools/harness/templates/project-task-template.json" -Section "file" -Message "缺少 project-task-template，无法承载第三章计划约束。"
}
else {
  if (-not (Test-ContainsAll -Content $taskTemplate -Terms @("INIT-001", "ANALYSIS-001", "TESTCASE-001", "PLAN-001", "seed queue", "feature-task-reference.json"))) {
    $issues += New-Issue -Severity "error" -File "tools/harness/templates/project-task-template.json" -Section "seed-queue-fields" -Message "project-task-template 没有清晰表达四阶段 seed queue 和 feature-task-reference 的分层关系。"
  }
}

if ($null -eq $featureTaskReference) {
  $issues += New-Issue -Severity "error" -File "tools/harness/templates/feature-task-reference.json" -Section "file" -Message "缺少 feature-task-reference，无法为后续 feature_impl / release 任务提供蓝本。"
}
else {
  if (Test-ContainsPlaceholder -Content $featureTaskReference) {
    $issues += New-Issue -Severity "warning" -File "tools/harness/templates/feature-task-reference.json" -Section "placeholders" -Message "feature-task-reference 仍包含占位符；这是模板预期，但需要保证完整字段存在。"
  }
  if (-not (Test-ContainsAll -Content $featureTaskReference -Terms @("qa_contract", "required_layers", "tdd_contract", "architecture_constraints", "forbidden_implementations", "story_full_chain", "acceptance_validation"))) {
    $issues += New-Issue -Severity "error" -File "tools/harness/templates/feature-task-reference.json" -Section "implementation-fields" -Message "feature-task-reference 缺少后续 feature_impl / release 任务所需的 QA 和架构字段。"
  }
  if (-not (Test-ContainsAll -Content $featureTaskReference -Terms @("模块归属", "文件改动清单", "复用内容", "新增内容", "不改内容", "风险点", "测试范围"))) {
    $issues += New-Issue -Severity "error" -File "tools/harness/templates/feature-task-reference.json" -Section "design-plan-fields" -Message "feature-task-reference 缺少复杂功能技术方案字段。"
  }
}

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

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

exit $exitCode
