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

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

  return $true
}

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

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

  return $null
}

$issues = @()

$taskSchemaPath = Resolve-FirstExistingPath -Candidates @(
  (Join-Path $ProjectRoot "docs\harness\task.schema.json"),
  (Join-Path $ProjectRoot "docs\codex-harness-engineering\templates\runtime\task.schema.json")
)
$projectTemplatePath = Join-Path $ProjectRoot "tools\harness\templates\project-task-template.json"
$featureTemplatePath = Join-Path $ProjectRoot "tools\harness\templates\feature-task-reference.json"
$implementPromptPath = Join-Path $ProjectRoot ".codex\prompts\implement-one-task.md"
$stage1PromptPath = Join-Path $ProjectRoot ".codex\prompts\review-stage1-spec.md"
$stage2PromptPath = Join-Path $ProjectRoot ".codex\prompts\review-stage2-quality.md"

$taskSchema = Get-FileContentOrNull -Path $taskSchemaPath
if ($null -eq $taskSchema) {
  $issues += New-Issue -Severity "error" -File "docs/harness/task.schema.json" -Section "file" -Message "缺少 task schema，无法把 task.json 作为执行合同约束。"
}
elseif (-not (Test-ContainsAll -Content $taskSchema -Terms @('"title"', '"task_kind"', '"depth"', '"risk"', '"owned_paths"', '"forbidden_paths"', '"required_truth_sources"', '"produces_artifacts"', '"acceptance"', '"qa_contract"', '"test_command"', '"human_approval_required"', '"rollback_plan_required"', '"security_review_required"', '"migration_review_required"', '"impact_analysis_required"', '"impact_analysis_summary"', '"implementation_plan_summary"', '"test_strategy_required"', '"test_plan_summary"', '"permission_cases"', '"security_cases"'))) {
  $issues += New-Issue -Severity "error" -File "docs/harness/task.schema.json" -Section "schema" -Message "task schema 缺少关键任务协议字段约束。"
}

$projectTemplate = Get-FileContentOrNull -Path $projectTemplatePath
if ($null -eq $projectTemplate -or -not (Test-ContainsAll -Content $projectTemplate -Terms @('"id"', '"title"', '"type"', '"description"', '"priority"', '"dependencies"', '"passes"', '"context_files"', '"owned_paths"', '"forbidden_paths"', '"required_truth_sources"', '"produces_artifacts"', '"acceptance"', '"test_command"'))) {
  $issues += New-Issue -Severity "error" -File "tools/harness/templates/project-task-template.json" -Section "template" -Message "project-task-template 缺少基础或边界协议字段。"
}

$featureTemplate = Get-FileContentOrNull -Path $featureTemplatePath
if ($null -eq $featureTemplate -or -not (Test-ContainsAll -Content $featureTemplate -Terms @('"title"', '"type"', '"depth"', '"risk"', '"allowed_dependencies"', '"forbidden_paths"', '"qa_contract"', '"blocked_if_missing"', '"human_approval_required"', '"rollback_plan_required"', '"security_review_required"', '"migration_review_required"', '"impact_analysis_required"', '"impact_analysis_summary"', '"implementation_plan_summary"', '"test_strategy_required"', '"test_plan_summary"', '"permission_cases"', '"security_cases"'))) {
  $issues += New-Issue -Severity "error" -File "tools/harness/templates/feature-task-reference.json" -Section "template" -Message "feature-task-reference 缺少完整执行合同字段。"
}

$implementPrompt = Get-FileContentOrNull -Path $implementPromptPath
if ($null -eq $implementPrompt -or -not (Test-ContainsAll -Content $implementPrompt -Terms @("标题", "produces_artifacts", "human_approval_required", "rollback_plan_required", "security_review_required", "migration_review_required", "### Phase 3: Impact Analysis", "### Phase 4: Implementation Plan", "Implementation Plan Summary", "### Phase 5: Test Plan", "permission_cases", "security_cases", "owned_paths", "rollback consideration"))) {
  $issues += New-Issue -Severity "error" -File ".codex/prompts/implement-one-task.md" -Section "prompt" -Message "implement prompt 未完整读取任务协议字段。"
}

$stage1Prompt = Get-FileContentOrNull -Path $stage1PromptPath
if ($null -eq $stage1Prompt -or -not (Test-ContainsAll -Content $stage1Prompt -Terms @("depth", "risk", "qa_contract.depth_protocol", "owned_paths", "forbidden_paths", "allowed_dependencies"))) {
  $issues += New-Issue -Severity "error" -File ".codex/prompts/review-stage1-spec.md" -Section "prompt" -Message "Stage 1 prompt 缺少任务协议字段检查。"
}

$stage2Prompt = Get-FileContentOrNull -Path $stage2PromptPath
if ($null -eq $stage2Prompt -or -not (Test-ContainsAll -Content $stage2Prompt -Terms @("无关 diff", "未批准依赖变更", "positive_cases", "negative_cases", "boundary_cases", "regression_cases", "human_approval_required", "rollback_plan_required", "security_review_required", "migration_review_required"))) {
  $issues += New-Issue -Severity "error" -File ".codex/prompts/review-stage2-quality.md" -Section "prompt" -Message "Stage 2 prompt 缺少任务协议字段消费或高风险位检查。"
}

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

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

exit $exitCode
