#!/bin/bash
# CI wrapper for push-triggered builds on astra.
# Called by the post-receive hook on Hetzner via SSH.
#
# Pulls latest code, runs the CI suite, reports results to WAM.
# If tests fail on main, auto-reverts the offending commit(s) and pushes
# the revert — enforcing the no-regressions rule from operations.md.
#
# Location on astra: /home/max/mnw-ci/server/deploy/ci-on-push.sh
# Usage: ci-on-push.sh [branch_name]

set -uo pipefail

export PATH="$HOME/.cargo/bin:$PATH"

BRANCH="${1:-main}"
REPO_DIR="$HOME/mnw-ci"
SERVER_DIR="$REPO_DIR/server"
WAM_URL="${WAM_URL:-http://127.0.0.1:7890}"
START_TIME=$(date +%s)
LOG_FILE="$REPO_DIR/ci-latest.log"

echo "=== CI triggered for branch: $BRANCH ==="
echo "Started: $(date -u +%Y-%m-%dT%H:%M:%SZ)"

# Pull latest code
cd "$REPO_DIR" || exit 1
echo "[pull] Fetching latest..."
git fetch origin "$BRANCH" 2>&1

# Record what we're about to test
OLD_HEAD=$(git rev-parse HEAD 2>/dev/null || echo "none")
git reset --hard "origin/$BRANCH" 2>&1
NEW_HEAD=$(git rev-parse HEAD)
COMMIT_MSG=$(git log --oneline -1)

echo "[pull] $OLD_HEAD -> $NEW_HEAD"
echo "[pull] $COMMIT_MSG"

# Run CI from the server directory
cd "$SERVER_DIR" || exit 1

export DATABASE_URL="${DATABASE_URL:-postgres:///makenotwork_staging}"
export TEST_DATABASE_URL="${TEST_DATABASE_URL:-postgres:///postgres}"
export RUST_TEST_THREADS="${RUST_TEST_THREADS:-8}"
export CARGO_INCREMENTAL=0
export RUST_BACKTRACE=1

echo "[ci] Running CI suite..."
CI_OUTPUT=$("$REPO_DIR/server/deploy/run-ci.sh" 2>&1) || true
CI_EXIT=$?

END_TIME=$(date +%s)
DURATION=$(( END_TIME - START_TIME ))

# Extract summary from CI output
PASS_COUNT=$(echo "$CI_OUTPUT" | grep -c "^  PASS" || true)
FAIL_COUNT=$(echo "$CI_OUTPUT" | grep -c "^  FAIL" || true)

# Save full log
echo "$CI_OUTPUT" > "$LOG_FILE"

# --- Handle results ---

wam_ticket() {
    local title="$1" body="$2" priority="$3" source_ref="$4"
    local escaped_title escaped_body
    escaped_title=$(echo "$title" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read().strip()))' 2>/dev/null || echo "\"$title\"")
    escaped_body=$(echo "$body" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))' 2>/dev/null || echo '""')
    curl -sf -X POST "$WAM_URL/tickets" \
        -H "Content-Type: application/json" \
        -d "{\"title\": $escaped_title, \"body\": $escaped_body, \"priority\": \"$priority\", \"source\": \"ci\", \"source_ref\": \"$source_ref\"}" \
        >/dev/null 2>&1 || echo "[warn] Failed to create WAM ticket"
}

if [ $CI_EXIT -eq 0 ]; then
    # --- CI PASSED ---
    TITLE="CI passed: $BRANCH ($PASS_COUNT steps, ${DURATION}s)"
    BODY="Commit: $COMMIT_MSG
Duration: ${DURATION}s
Steps passed: $PASS_COUNT

All steps passed."

    wam_ticket "$TITLE" "$BODY" "low" "$NEW_HEAD"
    echo ""
    echo "=== CI PASSED ($PASS_COUNT steps, ${DURATION}s) ==="
else
    # --- CI FAILED — AUTO-REVERT ---
    FAILED_STEPS=$(echo "$CI_OUTPUT" | grep "^  FAIL" | sed 's/^  FAIL  /  - /')

    echo ""
    echo "=== CI FAILED — REVERTING ==="
    echo ""

    cd "$REPO_DIR" || exit 1

    # Count how many new commits since old head
    if [ "$OLD_HEAD" = "none" ] || [ "$OLD_HEAD" = "$NEW_HEAD" ]; then
        # Can't determine what to revert (first run or no change)
        REVERT_STATUS="could not determine commits to revert"
    else
        NEW_COMMITS=$(git rev-list "$OLD_HEAD..$NEW_HEAD" --count 2>/dev/null || echo "0")

        if [ "$NEW_COMMITS" -eq 1 ]; then
            # Single commit — revert it
            git revert --no-edit HEAD 2>&1
            REVERT_STATUS="reverted 1 commit ($NEW_HEAD)"
        elif [ "$NEW_COMMITS" -gt 1 ]; then
            # Multiple commits — revert the range
            git revert --no-edit "$OLD_HEAD..$NEW_HEAD" 2>&1
            REVERT_STATUS="reverted $NEW_COMMITS commits ($OLD_HEAD..$NEW_HEAD)"
        else
            REVERT_STATUS="no new commits to revert"
        fi

        # Push the revert back to origin
        if git push origin "$BRANCH" 2>&1; then
            REVERT_STATUS="$REVERT_STATUS — pushed to origin"
        else
            REVERT_STATUS="$REVERT_STATUS — PUSH FAILED (manual intervention needed)"
        fi
    fi

    TITLE="CI FAILED + REVERTED: $BRANCH ($FAIL_COUNT step(s) failed)"
    BODY="Commit: $COMMIT_MSG
Duration: ${DURATION}s
Steps passed: $PASS_COUNT
Steps failed: $FAIL_COUNT

Failed steps:
$FAILED_STEPS

Revert: $REVERT_STATUS

No-regressions rule enforced automatically.
Fix the issue and re-push.

Last 30 lines of output:
$(echo "$CI_OUTPUT" | tail -30)"

    wam_ticket "$TITLE" "$BODY" "critical" "$NEW_HEAD"
    echo "Revert: $REVERT_STATUS"
    echo ""
fi

exit $CI_EXIT
