#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
cd "$ROOT"

# These ceilings are debt ratchets, not desired steady-state values. Their
# ownership, rationale, and retirement conditions are documented in the
# matching guardrail README. Lower a ceiling whenever the inventory shrinks.
failures=()

# Guardrails are independent, read-only static checks, so they can run
# concurrently. Each `run` call enqueues one check; jobs execute with bounded
# concurrency (HARNESS_FAST_JOBS, default 4) and each job's output is captured
# to a temp file. On completion a deterministic [harness:timing] line is
# emitted to stderr and any failing job's output is replayed. All jobs run
# regardless of individual failures, and the aggregate failure report is
# printed in declaration order -- the same contract as the previous serial
# agentteam, but with a wall-clock that scales with the slowest checks instead of
# their sum.
harness_tmp="$(mktemp -d "${TMPDIR:-/tmp}/agentteam-harness-fast.XXXXXX")"
trap 'rm -rf "${harness_tmp}"' EXIT
harness_max_jobs="${HARNESS_FAST_JOBS:-4}"
if (( harness_max_jobs < 1 )); then
  harness_max_jobs=1
fi
harness_next_job=0
harness_running_pids=()
harness_all_pids=()
harness_labels=()

harness_now_ms() {
  local value
  value="$(date +%s%3N 2>/dev/null || true)"
  if [[ "${value}" =~ ^[0-9]+$ ]]; then
    printf '%s\n' "${value}"
    return
  fi
  printf '%s000\n' "$(date +%s)"
}

run() {
  local label="$*"
  local job_id="${harness_next_job}"
  harness_next_job=$((harness_next_job + 1))
  harness_labels+=("${label}")

  # Block for a free slot before launching another concurrent job.
  while (( ${#harness_running_pids[@]} >= harness_max_jobs )); do
    wait "${harness_running_pids[0]}" || true
    harness_running_pids=("${harness_running_pids[@]:1}")
  done

  printf '\n== %s ==\n' "${label}"
  (
    local started_at finished_at status
    started_at="$(harness_now_ms)"
    set +e
    "$@" >"${harness_tmp}/job.${job_id}.out" 2>&1
    status=$?
    set -e
    finished_at="$(harness_now_ms)"
    printf '%s\n' "${status}" >"${harness_tmp}/status.${job_id}"
    printf '[harness:timing] job=%s script=harness-fast label=%s status=%s duration_ms=%s\n' \
      "${job_id}" "${label}" "${status}" "$((finished_at - started_at))" \
      >"${harness_tmp}/timing.${job_id}"
  ) &
  harness_running_pids+=("$!")
  harness_all_pids+=("$!")
}

wait_for_harness_checks() {
  local job_id=0 pid wait_status status
  for pid in "${harness_all_pids[@]}"; do
    if wait "${pid}"; then
      wait_status=0
    else
      wait_status=$?
    fi
    if [[ -f "${harness_tmp}/status.${job_id}" ]]; then
      status="$(cat "${harness_tmp}/status.${job_id}")"
    else
      status="${wait_status}"
    fi
    if [[ -f "${harness_tmp}/timing.${job_id}" ]]; then
      cat "${harness_tmp}/timing.${job_id}" >&2
    fi
    if [[ "${status}" != "0" ]]; then
      failures+=("${harness_labels[${job_id}]} (exit ${status})")
      if [[ -s "${harness_tmp}/job.${job_id}.out" ]]; then
        printf '  --- output of %s ---\n' "${harness_labels[${job_id}]}" >&2
        cat "${harness_tmp}/job.${job_id}.out" >&2
      fi
    fi
    job_id=$((job_id + 1))
  done
}

run make check-electron-cutover
run env bash guardrails/desktop/check-no-isolated-execution-test.sh
run env bash guardrails/desktop/check-no-isolated-execution.sh
run env bash guardrails/repository/no-superpowers-docs.sh
run env bash guardrails/repository/check-no-committed-secrets.sh
run env bash guardrails/repository/no-extension-compiler-test.sh
run env bash guardrails/repository/no-extension-compiler.sh
run env bash guardrails/repository/no-global-extension-egress-test.sh
run env bash guardrails/repository/no-global-extension-egress.sh
run env bash guardrails/repository/no-vague-extension-names-test.sh
run env bash guardrails/repository/no-vague-extension-names.sh
run env python3 guardrails/repository/no-retired-mail-leak-test.py
run env python3 guardrails/repository/no-retired-mail-leak.py
run env bash guardrails/repository/no-retired-desktop-extension-test.sh
run env bash guardrails/repository/no-retired-desktop-extension.sh
run env bash guardrails/repository/specs-and-guardrails-layout.sh
run env bash guardrails/repository/check-agent-entry-skills.sh
run env bash guardrails/repository/check-skills-layout.sh
run env bash guardrails/repository/docker-build-contexts.sh
run env python3 guardrails/repository/check-go-package-names-test.py
run env python3 guardrails/repository/check-go-package-names.py
run env bash scripts/ci-backend-required-test.sh
run env bash guardrails/storage/tidb-migration-history-test.sh
run env bash guardrails/storage/tidb-migration-history.sh
run env python3 guardrails/repository/check-code-shape-test.py
run env python3 guardrails/repository/check-test-quality-test.py
run env python3 guardrails/repository/check-guarded-writers.py
# The remaining Task unread/fanout wrappers are intentional port and facade
# seams: they distinguish live versus recovered application and periodic versus
# completion-barrier persistence without leaking those modes across packages.
run env python3 guardrails/repository/check-code-shape.py \
  --max-files-over-soft-threshold 122 \
  --max-files-over-hard-threshold 22 \
  --max-go-functions-over-threshold 205 \
  --max-go-thin-wrappers 1321
run env python3 guardrails/repository/check-test-quality.py \
  --max-fixed-waits 59 \
  --max-overbroad-mocks 0 \
  --max-snapshot-assertions 0 \
  --max-focused-tests 0 \
  --max-skipped-tests 0 \
  --max-large-test-files 159 \
  --max-source-assertion-test-files 220 \
  --max-tidb-fixtures-in-subtests 34
run env python3 guardrails/repository/check-performance-static.py \
  --max-select-star 0 \
  --max-production-sleeps 3 \
  --max-uncancellable-timer-waits 0 \
  --max-db-calls-in-agentteams 40
run env python3 guardrails/repository/check-frontend-quality.py \
  --max-direct-fetch-outside-api-client 0 \
  --max-polling-intervals 5 \
  --max-uncapped-promise-all 13 \
  --max-direct-button-outside-ui 214 \
  --max-direct-input-outside-ui 0 \
  --max-cjk-literals 6
run env bash guardrails/api/internal-api-clean-code-design.sh
run env bash guardrails/api/workspace-url-callers.sh
run env bash guardrails/api/internal-cause-observation.sh
run env bash guardrails/api/dependency-invariant-round10.sh
run env bash guardrails/architecture/check-service-automation-architecture-test.sh
run env bash guardrails/architecture/check-service-automation-architecture.sh
run env bash guardrails/architecture/check-meshx-service-boundaries.sh
run env bash guardrails/ags/check-internal-identity-boundary.sh
run env bash guardrails/ags/check-repository-mutation-boundary.sh
run env bash guardrails/ags/check-content-store-tree-contract.sh
run env bash guardrails/message/direct-no-outbox.sh --check-only
run env bash guardrails/naming/semantic-terminology.sh --check
run env bash guardrails/message/task-channel-authority.sh
run env bash guardrails/observability/check-observability-test.sh
run env bash guardrails/observability/check-observability.sh

# Eight new tags are the durable v1-to-v2 scope-outbox contract: three optional
# recipient/projection fields plus the five-field conversation projection.
run env python3 guardrails/store/check-store-json-tags.py \
  --max-json-tagged-lines 350 \
  --max-json-operations 95 \
  --max-forbidden-edges 0
run env python3 guardrails/store/check-store-domain-split-guardrails-test.py
run env python3 guardrails/store/check-store-domain-split-guardrails.py
run env bash guardrails/store/check-api-dto-store-boundary-test.sh

run env \
  STORE_REFACTOR_MAX_API_HANDLER_STORE_REFS=69 \
  STORE_REFACTOR_MAX_API_STORE_MODEL_REFS=14 \
  STORE_REFACTOR_MAX_API_ROOT_STORE_IMPORTS=1 \
  STORE_REFACTOR_MAX_ROOT_STORE_FILES=1 \
  STORE_REFACTOR_MAX_ROOT_STORE_TEST_FILES=1 \
  STORE_REFACTOR_MAX_ROOT_STORE_UNAPPROVED_FILES=0 \
  STORE_REFACTOR_MAX_ROOT_STORE_GRAPH_METHODS=1 \
  STORE_REFACTOR_MAX_ROOT_STORE_TYPE_ALIASES=0 \
  STORE_REFACTOR_MAX_OBVIOUS_NOOP_IMPORT_ALIASES=18 \
  STORE_REFACTOR_MAX_PHASE10_REWIND_METHODS=27 \
  STORE_REFACTOR_MAX_PHASE10_REACTION_METHODS=5 \
  STORE_REFACTOR_MAX_PHASE10_REVIEW_METHODS=0 \
  STORE_REFACTOR_MAX_PHASE10_AGENT_OPS_METHODS=4 \
  STORE_REFACTOR_MAX_PHASE10_APP_ECOSYSTEM_METHODS=211 \
  STORE_REFACTOR_MAX_PRODUCTION_ROOT_STORE_IMPORT_FILES=4 \
  STORE_REFACTOR_MAX_STORE_LEGACY_USECASE_IMPORT_FILES=0 \
  STORE_REFACTOR_MAX_STORE_DOMAIN_ROOT_IMPORT_FILES=1 \
  bash guardrails/store/check-store-refactor-boundaries.sh
run env bash guardrails/store/check-app-canonical-runtime.sh

run env \
  AGENTTEAM_WEB_WORKSPACE_BOUNDARY_MAX_ROOT_FILE_VIOLATIONS=0 \
  AGENTTEAM_WEB_WORKSPACE_BOUNDARY_MAX_IMPORT_VIOLATIONS=0 \
  bash guardrails/web/workspace-boundaries.sh
run env bash guardrails/web/reload-and-internal-navigation.sh
run env bash guardrails/web/sidebar-typography.sh

wait_for_harness_checks

if (( ${#failures[@]} > 0 )); then
  printf '\nHarness fast checks failed (%d):\n' "${#failures[@]}" >&2
  printf '  - %s\n' "${failures[@]}" >&2
  exit 1
fi

printf '\nHarness fast checks passed.\n'
