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

echo "Running lockpick pre-commit check..."

if ! lockpick; then
  echo ""
  echo "ERROR: lockpick failed. Commit aborted."
  echo "Fix the reported issues and run lockpick successfully before committing."
  exit 1
fi

echo "lockpick passed."

echo "Running license header check..."

if ! ./.github/check-license-headers.sh; then
  echo ""
  echo "ERROR: License header check failed. Commit aborted."
  echo "Add the correct license header to all source files before committing."
  exit 1
fi

if [ "${ANDLOCK_SKIP_COVERAGE:-0}" = "1" ]; then
  echo "Skipping coverage gate (ANDLOCK_SKIP_COVERAGE=1)."
else
  echo "Running 100% coverage check (cargo llvm-cov --branch)..."

  if ! cargo llvm-cov --version >/dev/null 2>&1; then
    echo ""
    echo "ERROR: cargo-llvm-cov is not installed. Commit aborted."
    echo "Install it with: cargo install cargo-llvm-cov"
    exit 1
  fi

  PYTHON_BIN=""
  for candidate in python python3 py; do
    if command -v "$candidate" >/dev/null 2>&1; then
      PYTHON_BIN="$candidate"
      break
    fi
  done
  if [ -z "$PYTHON_BIN" ]; then
    echo ""
    echo "ERROR: No Python interpreter found (looked for python, python3, py)."
    echo "Install Python 3 to enable the coverage gate."
    exit 1
  fi

  COVERAGE_JSON="$(mktemp -t andlock-coverage.XXXXXX)"
  trap 'rm -f "$COVERAGE_JSON"' EXIT

  if ! cargo llvm-cov --branch --json --summary-only --output-path "$COVERAGE_JSON" >/dev/null; then
    echo ""
    echo "ERROR: cargo llvm-cov failed. Commit aborted."
    echo "Branch coverage requires the nightly toolchain. Install it with:"
    echo "  rustup toolchain install nightly --component llvm-tools-preview"
    exit 1
  fi

  # lockpick does not yet expose coverage gating, so we enforce it here.
  # We require 100% on functions, lines, regions and branches across the
  # whole crate, checked on the report-wide totals. count == 0 on any
  # metric is treated as failure: an empty totals block means the report
  # is bogus (broken instrumentation, no tests collected, branch coverage
  # not enabled because the toolchain is stable, etc.) and must not pass.
  if ! "$PYTHON_BIN" - "$COVERAGE_JSON" <<'PY'
import json
import sys

try:
    with open(sys.argv[1], encoding="utf-8") as fh:
        data = json.load(fh)
except (OSError, ValueError) as exc:
    print(f"  FAIL  could not read coverage JSON: {exc}")
    sys.exit(1)

entries = data.get("data") or []
if not entries:
    print("  FAIL  coverage report contains no data entries")
    sys.exit(1)

metrics = ("functions", "lines", "regions", "branches")
failed = False

for index, entry in enumerate(entries):
    totals = entry.get("totals") or {}
    files = entry.get("files") or []
    if not files:
        print(f"  FAIL  entry {index} has no files")
        failed = True
        continue
    for metric in metrics:
        bucket = totals.get(metric) or {}
        count = bucket.get("count", 0)
        covered = bucket.get("covered", 0)
        percent = bucket.get("percent", 0.0)
        if not isinstance(count, int) or not isinstance(covered, int):
            print(f"  FAIL  {metric}: malformed entry {bucket!r}")
            failed = True
            continue
        if count == 0:
            hint = ""
            if metric == "branches":
                hint = " (branch coverage requires the nightly toolchain)"
            print(f"  FAIL  {metric}: count is 0{hint}")
            failed = True
        elif covered != count:
            print(f"  FAIL  {metric}: {covered}/{count} ({percent:.4f}%)")
            failed = True
        else:
            print(f"  OK    {metric}: {covered}/{count} (100%)")

sys.exit(1 if failed else 0)
PY
  then
    echo ""
    echo "ERROR: Coverage is not 100%. Commit aborted."
    echo "Run 'cargo cov' for the HTML report and add the missing tests."
    echo "Set ANDLOCK_SKIP_COVERAGE=1 to bypass this check temporarily."
    exit 1
  fi

  echo "Coverage is 100%."
fi

echo "All pre-commit checks passed. Proceeding with commit."
