#!/usr/bin/env bash
# scripts/ci-detect-already-validated.sh — emit `skip=true|false` to $GITHUB_OUTPUT for the
# docker-build.yml cross-run tree-identity gate (ersatztv#420). On a merge-to-main push, if the
# merged tree is byte-identical to a PR head that ALREADY passed `test`+`migrations` (a GREEN
# combined commit status), the heavy compile/test/migrations work is redundant -- the exact same
# source was already validated. `build` still runs and still builds+pushes the image, so no image
# ever ships from unvalidated source.
#
# The bias is ALWAYS toward running MORE, never less: a false 'true' would ship (or claim to
# validate) unreviewed/unvalidated source, so every ambiguous or unverifiable case resolves to
# skip=false. It is fine (just wasteful) to re-run on an identical tree; it is a correctness bug
# to skip validation on a tree that differs or was never proven green.
#
# Runs identically locally and in CI. Locally (no $GITHUB_OUTPUT) it prints the decision to
# stdout; e.g. GITHUB_EVENT_NAME=push GITHUB_REF=refs/heads/main scripts/ci-detect-already-validated.sh
set -euo pipefail

out="${GITHUB_OUTPUT:-/dev/stdout}"
event="${GITHUB_EVENT_NAME:-}"
ref="${GITHUB_REF:-}"

emit() {
  echo "skip=$1" >> "$out"
  echo "-> skip=$1"
}

# Only a push directly to main can possibly be a merge-to-main we can cross-check against an
# already-validated PR head. Everything else (pull_request, tag push, workflow_dispatch, a push
# to any other branch) -> always run.
if [ "$event" != "push" ] || [ "$ref" != "refs/heads/main" ]; then
  echo "event='${event:-<none>}' ref='${ref:-<none>}' (need push to refs/heads/main); running full validation (safe default)"
  emit false
  exit 0
fi

# Deepen history so HEAD's second parent (and its tree) are resolvable -- a shallow checkout may
# have neither. Mirrors the docs-only/docs-reminder jobs' fetch style. Non-fatal: a failed
# deepen still falls through to the HEAD^2 check below, which then fails safe.
git fetch --deepen=2 origin 2>/dev/null || git fetch --unshallow origin 2>/dev/null || true

# HEAD must be a real merge commit with a second parent -- that second parent is the PR head CI
# actually validated. No second parent (a direct/fast-forward/squash push) -> nothing to compare
# against -> always run.
pr_head="$(git rev-parse --verify -q HEAD^2 || true)"
if [ -z "$pr_head" ]; then
  echo "HEAD has no second parent (not a merge commit); running full validation (safe default)"
  emit false
  exit 0
fi

merge_tree="$(git rev-parse --verify -q 'HEAD^{tree}' || true)"
pr_tree="$(git rev-parse --verify -q "${pr_head}^{tree}" || true)"
if [ -z "$merge_tree" ] || [ -z "$pr_tree" ]; then
  echo "could not resolve HEAD or HEAD^2 tree; running full validation (safe default)"
  emit false
  exit 0
fi

if [ "$merge_tree" != "$pr_tree" ]; then
  echo "merged tree ($merge_tree) != PR head $pr_head tree ($pr_tree) -- main advanced since the PR was validated; running full validation"
  emit false
  exit 0
fi

# Merge tree matches the PR head tree exactly. Confirm that PR head was actually validated green
# before trusting it -- query the Gitea combined commit status API. Auth is required (private
# instance); a missing/failing/non-success response always falls through to skip=false.
if [ -z "${ETV_STATUS_AUTH:-}" ]; then
  echo "ETV_STATUS_AUTH not set; cannot verify PR head status; running full validation (safe default)"
  emit false
  exit 0
fi

status_url="http://192.168.1.95:3000/api/v1/repos/timothy/ersatztv/commits/${pr_head}/status"
status_json="$(curl -sf -u "$ETV_STATUS_AUTH" "$status_url" || true)"
if [ -z "$status_json" ]; then
  echo "status API request for PR head ${pr_head} failed; running full validation (safe default)"
  emit false
  exit 0
fi

state="$(printf '%s' "$status_json" | jq -r '.state // empty' 2>/dev/null || true)"
if [ "$state" != "success" ]; then
  echo "PR head ${pr_head} combined status is '${state:-<unknown>}', not 'success'; running full validation (safe default)"
  emit false
  exit 0
fi

echo "merged tree == green PR head ${pr_head} (status=success) -> skipping re-validation"
emit true
