#!/bin/bash
# Pre-push hook — blocks push unless pre-push-validate.sh has been run.
# Validates the marker file is fresh and matches the current commit.
#
# Install: git config core.hooksPath .githooks

set -e

GIT_DIR="$(git rev-parse --git-dir)"
MARKER_FILE="$GIT_DIR/validation-passed"
VALIDATION_TTL_MINUTES=30

# Skip validation for branch deletes
ZERO_SHA="0000000000000000000000000000000000000000"
IS_DELETE=true

while read -r local_ref local_sha remote_ref remote_sha; do
    if [ "$local_sha" != "$ZERO_SHA" ]; then
        IS_DELETE=false
        break
    fi
done

if [ "$IS_DELETE" = true ]; then
    exit 0
fi

# Escape hatch for sandboxed environments where Maven Central /
# embabel-releases are unreachable and pre-push-validate.sh cannot run
# (CI runners, cloud coding sandboxes, disconnected environments).
#
# Two signals are required — intentionally:
#   1. ATMOSPHERE_OFFLINE_PUSH=1          — explicit operator intent
#   2. A sandbox/CI marker env var       — proves we're in an environment
#      that genuinely can't reach Maven (not a local dev machine that just
#      happens to have the flag in their shell profile)
#
# Accepted sandbox markers: CI, GITHUB_ACTIONS, CODESPACES,
# CLAUDE_CODE_SANDBOX, ATMOSPHERE_SANDBOX. On a local dev machine none of
# these should be set, so the escape hatch stays inert and the safety
# gate remains intact.
if [ -n "$ATMOSPHERE_OFFLINE_PUSH" ]; then
    if [ -z "$CI" ] && [ -z "$GITHUB_ACTIONS" ] && [ -z "$CODESPACES" ] \
            && [ -z "$CLAUDE_CODE_SANDBOX" ] && [ -z "$ATMOSPHERE_SANDBOX" ]; then
        echo "🚫 ATMOSPHERE_OFFLINE_PUSH ignored — not in a recognised sandbox." >&2
        echo "   This bypass is only honoured when one of CI, GITHUB_ACTIONS," >&2
        echo "   CODESPACES, CLAUDE_CODE_SANDBOX, or ATMOSPHERE_SANDBOX is set." >&2
        echo "   Run ./scripts/pre-push-validate.sh before pushing." >&2
        exit 1
    fi
    echo "INFO: ATMOSPHERE_OFFLINE_PUSH honoured (sandbox detected) —"
    echo "      skipping validation marker check. Verify the build locally"
    echo "      (standalone javac / junit console) before pushing."
    exit 0
fi

CURRENT_COMMIT=$(git rev-parse HEAD)

print_blocked() {
    local reason="$1"
    echo ""
    echo "🚫 Push blocked — validation required"
    echo "======================================="
    echo ""
    echo "Reason: $reason"
    echo ""
    echo "Run validation first:"
    echo "  ./scripts/pre-push-validate.sh   # full build + tests (no --fast option)"
    echo ""
    echo "Then push:"
    echo "  git push"
    echo ""
    exit 1
}

# Check marker exists
if [ ! -f "$MARKER_FILE" ]; then
    print_blocked "No validation marker found"
fi

# Parse marker
MARKER_CONTENT=$(cat "$MARKER_FILE")
MARKER_TIMESTAMP=$(echo "$MARKER_CONTENT" | cut -d' ' -f1)
MARKER_COMMIT=$(echo "$MARKER_CONTENT" | cut -d' ' -f2)

# Check freshness
CURRENT_TIMESTAMP=$(date +%s)
AGE_SECONDS=$((CURRENT_TIMESTAMP - MARKER_TIMESTAMP))
AGE_MINUTES=$((AGE_SECONDS / 60))
TTL_SECONDS=$((VALIDATION_TTL_MINUTES * 60))

if [ "$AGE_SECONDS" -gt "$TTL_SECONDS" ]; then
    print_blocked "Validation expired (${AGE_MINUTES}m old, TTL is ${VALIDATION_TTL_MINUTES}m)"
fi

# Check commit matches
if [ "$MARKER_COMMIT" != "$CURRENT_COMMIT" ]; then
    print_blocked "Commit changed since validation (validated: ${MARKER_COMMIT:0:8}, current: ${CURRENT_COMMIT:0:8})"
fi

echo ""
echo "✅ Validation marker valid (${AGE_MINUTES}m ago)"
echo "🚀 Push proceeding..."
echo ""

# Consume the marker
rm -f "$MARKER_FILE"
