#!/usr/bin/env bash
# Canonical IPZ gate: the only success state is LANDED.
#
# Runs the full remote E2E gate and, on pass, immediately lands HEAD on
# origin/master as the tail of the same transaction. "green" is printed only
# after the push succeeds, and the receipt carries the landed master SHA — a
# receipt without one is incomplete by definition. Any failure in the land
# tail exits red ("NOT DONE — merge blocked: <reason>") so a stranded branch
# surfaces as a failed run, never as a green branch waiting for someone to
# remember it.
set -euo pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_DIR
readonly MAIN_BRANCH="${IPZ_GATE_MAIN_BRANCH:-master}"
readonly REMOTE="${IPZ_GATE_REMOTE:-origin}"
RECEIPT="${IPZ_GATE_RECEIPT:-}"

red() {
    printf 'NOT DONE — %s\n' "$*" >&2
    if [[ -n "${RECEIPT}" ]]; then
        printf 'outcome\tblocked\nreason\t%s\n' "$*" > "${RECEIPT}" || true
    fi
    exit 1
}

repo_root="$(git -C "${SCRIPT_DIR}" rev-parse --show-toplevel)" || red 'merge blocked: not inside a git repository'
head_sha="$(git -C "${repo_root}" rev-parse --verify HEAD)" || red 'merge blocked: unresolvable HEAD'

if ! git -C "${repo_root}" diff --quiet || ! git -C "${repo_root}" diff --cached --quiet; then
    red 'merge blocked: uncommitted changes in the worktree — commit them before gating'
fi

"${SCRIPT_DIR}/run-remote.sh" || red "gate failed for ${head_sha} — nothing landed"

# The remote gate syncs regenerated screenshot artifacts back over their
# committed baselines; the spec asserts only that captures are non-empty, so
# the churn is generated output, not a result. Restore the baselines — the
# lander refuses a dirty source tree otherwise.
artifacts_dir="${SCRIPT_DIR}/../artifacts"
if [[ -d "${artifacts_dir}" ]] && ! git -C "${repo_root}" diff --quiet -- "${artifacts_dir}"; then
    git -C "${repo_root}" checkout HEAD -- "${artifacts_dir}" \
        || red 'merge blocked: cannot restore regenerated test artifacts to their committed baselines'
fi

# Land tail: route through the sanctioned lander. Raw pushes to the trunk are
# rejected by the harness land guard (pre-push) by design — the lander is the
# single serialized trunk writer, and it alone holds a land authority.
super_root="$(git -C "${repo_root}" rev-parse --path-format=absolute --git-common-dir)"
super_root="${super_root%/.git*}"
ship="${super_root}/.claude/scripts/ship.sh"
[[ -x "${ship}" || -f "${ship}" ]] || red "merge blocked: sanctioned lander missing at ${ship}"

branch="$(git -C "${repo_root}" rev-parse --abbrev-ref HEAD)"
[[ "${branch}" != "HEAD" ]] || red 'merge blocked: detached HEAD — the lander needs a branch'

# The lander removes the landed worktree, so it must run from outside it —
# and every post-land confirmation must use the super-root, not repo_root.
(cd "${super_root}" && bash "${ship}" land "${branch}" "${repo_root}") \
    || red "merge blocked: sanctioned lander refused ${branch} (${head_sha}) — read its JSON stage/next/detail and re-run"

git -C "${super_root}" fetch "${REMOTE}" "${MAIN_BRANCH}" \
    || red 'merge blocked: landed but cannot fetch to confirm'
landed="$(git -C "${super_root}" rev-parse --verify "${REMOTE}/${MAIN_BRANCH}")"
git -C "${super_root}" merge-base --is-ancestor "${head_sha}" "${landed}" \
    || red "merge blocked: lander exited 0 but ${head_sha} is not an ancestor of ${REMOTE}/${MAIN_BRANCH}"
if [[ -n "${RECEIPT}" ]]; then
    printf 'outcome\tgreen\nlanded_master_sha\t%s\n' "${landed}" > "${RECEIPT}"
fi
printf 'green — landed %s on %s/%s\n' "${landed}" "${REMOTE}" "${MAIN_BRANCH}"
