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-'
  )
}

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

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

  return $false
}

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

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

  return $true
}

$issues = @()

$repoMapPath = Join-Path $ProjectRoot "docs\ai\repo-map.md"
$currentTaskPath = Join-Path $ProjectRoot "docs\ai\CURRENT_TASK.md"
$apiMapPath = Join-Path $ProjectRoot "docs\ai\API_MAP.md"
$dbSchemaPath = Join-Path $ProjectRoot "docs\ai\DB_SCHEMA.md"
$architectureBriefPath = Join-Path $ProjectRoot "docs\ai\architecture-brief.md"

$repoMap = Get-FileContentOrNull -Path $repoMapPath
$currentTask = Get-FileContentOrNull -Path $currentTaskPath
$apiMap = Get-FileContentOrNull -Path $apiMapPath
$dbSchema = Get-FileContentOrNull -Path $dbSchemaPath
$architectureBrief = Get-FileContentOrNull -Path $architectureBriefPath

if ($null -eq $repoMap) {
  $issues += New-Issue -Severity "error" -File "docs/ai/repo-map.md" -Section "file" -Message "缺少 repo-map 导航入口。"
}
else {
  if (Test-ContainsPlaceholder -Content $repoMap) {
    $issues += New-Issue -Severity "error" -File "docs/ai/repo-map.md" -Section "placeholders" -Message "repo-map 仍包含占位符，代码导航事实未收敛。"
  }
  if (-not (Test-ContainsAll -Content $repoMap -Terms @("关键目录", "从哪里开始读", "常用命令"))) {
    $issues += New-Issue -Severity "error" -File "docs/ai/repo-map.md" -Section "minimum-sections" -Message "repo-map 缺少关键目录、阅读顺序或常用命令。"
  }
  if (-not (Test-ContainsAll -Content $repoMap -Terms @("入口", "调用链", "测试"))) {
    $issues += New-Issue -Severity "warning" -File "docs/ai/repo-map.md" -Section "code-navigation" -Message "repo-map 未明确入口、调用链或测试入口，难以支撑第二章的上下文定位。"
  }
}

if ($null -eq $architectureBrief) {
  $issues += New-Issue -Severity "warning" -File "docs/ai/architecture-brief.md" -Section "file" -Message "缺少 architecture-brief，模块级导航摘要不完整。"
}
elseif (Test-ContainsPlaceholder -Content $architectureBrief) {
  $issues += New-Issue -Severity "warning" -File "docs/ai/architecture-brief.md" -Section "placeholders" -Message "architecture-brief 仍包含占位符。"
}

if ($null -eq $currentTask) {
  $issues += New-Issue -Severity "error" -File "docs/ai/CURRENT_TASK.md" -Section "file" -Message "缺少 CURRENT_TASK 当前任务导航文件。"
}
else {
  if (-not (Test-ContainsAll -Content $currentTask -Terms @("任务目标", "验收标准", "owned paths", "风险点", "依赖的真相源", "关键验证命令", "暂时不要动的区域"))) {
    $issues += New-Issue -Severity "error" -File "docs/ai/CURRENT_TASK.md" -Section "minimum-fields" -Message "CURRENT_TASK 缺少任务目标、验收、owned paths、风险点、真相源、验证命令或 no-touch 区域。"
  }
  if (Test-ContainsPlaceholder -Content $currentTask) {
    $issues += New-Issue -Severity "warning" -File "docs/ai/CURRENT_TASK.md" -Section "placeholders" -Message "CURRENT_TASK 仍包含占位符，当前任务上下文可能未刷新。"
  }
}

if ($null -eq $apiMap) {
  $issues += New-Issue -Severity "warning" -File "docs/ai/API_MAP.md" -Section "file" -Message "缺少 API_MAP；如果项目有接口、路由或命令入口，应补齐。"
}
else {
  if (Test-ContainsPlaceholder -Content $apiMap) {
    $issues += New-Issue -Severity "warning" -File "docs/ai/API_MAP.md" -Section "placeholders" -Message "API_MAP 仍包含占位符。"
  }
  if (-not (Test-ContainsAny -Content $apiMap -Terms @("命令入口", "路由", "接口", "配置接口"))) {
    $issues += New-Issue -Severity "warning" -File "docs/ai/API_MAP.md" -Section "entrypoints" -Message "API_MAP 未明确对外入口类型。"
  }
}

if ($null -eq $dbSchema) {
  $issues += New-Issue -Severity "warning" -File "docs/ai/DB_SCHEMA.md" -Section "file" -Message "缺少 DB_SCHEMA；如果项目有数据模型或持久化边界，应补齐。"
}
else {
  if (Test-ContainsPlaceholder -Content $dbSchema) {
    $issues += New-Issue -Severity "warning" -File "docs/ai/DB_SCHEMA.md" -Section "placeholders" -Message "DB_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 "Context lint passed."
  exit 0
}

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

exit $exitCode
