#!/bin/bash
# Regression harness for pr-merge.sh Gitea non-interactive tea empty identity fallback.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WORK_ROOT="${AGENT_WORK_ROOT:-${HOME:-/tmp}/mosaic/agent-work}"
SANDBOX="$WORK_ROOT/pr-merge-empty-uid-test-$$"
MOCK_BIN="$SANDBOX/bin"
REPO_DIR="$SANDBOX/repo"
LOG_FILE="$SANDBOX/mock.log"

cleanup() {
    rm -rf "$SANDBOX"
}
trap cleanup EXIT

mkdir -p "$MOCK_BIN" "$REPO_DIR"
: > "$LOG_FILE"

cat > "$MOCK_BIN/tea" <<'EOF'
#!/bin/bash
set -euo pipefail
printf 'tea %q ' "$@" >> "$PR_MERGE_TEST_LOG"
printf '\n' >> "$PR_MERGE_TEST_LOG"
if [[ "$*" == *"login list"* ]]; then
    echo '[{"name":"git.mosaicstack.dev","url":"https://git.mosaicstack.dev"}]'
    exit 0
fi
if [[ "$*" == *"pr merge"* ]]; then
    echo 'user does not exist [uid: 0, name: ]' >&2
    exit 1
fi
exit 0
EOF
chmod +x "$MOCK_BIN/tea"

cat > "$MOCK_BIN/curl" <<'EOF'
#!/bin/bash
set -euo pipefail
printf 'curl %q ' "$@" >> "$PR_MERGE_TEST_LOG"
printf '\n' >> "$PR_MERGE_TEST_LOG"
args=" $* "
out_file=""
write_code=false
post_data=""
prev=""
for arg in "$@"; do
    if [[ "$prev" == "-o" ]]; then
        out_file="$arg"
        prev=""
        continue
    fi
    if [[ "$prev" == "-d" ]]; then
        post_data="$arg"
        prev=""
        continue
    fi
    if [[ "$arg" == "-o" ]]; then
        prev="-o"
        continue
    fi
    if [[ "$arg" == "-d" ]]; then
        prev="-d"
        continue
    fi
    if [[ "$arg" == "-w" ]]; then
        write_code=true
    fi
done
emit_response() {
    local body="$1"
    if [[ -n "$out_file" ]]; then
        printf '%s' "$body" > "$out_file"
    else
        printf '%s' "$body"
    fi
    if [[ "$write_code" == true ]]; then
        printf '200'
    fi
}
if [[ "$args" == *"/api/v1/repos/mosaicstack/stack/pulls/123"* && "$args" != *"/api/v1/repos/mosaicstack/stack/pulls/123/merge"* ]]; then
    emit_response '{"number":123,"title":"mock","state":"open","user":{"login":"tester"},"head":{"ref":"feature/mock"},"base":{"ref":"main"},"labels":[],"assignees":[],"html_url":"https://git.mosaicstack.dev/mosaicstack/stack/pulls/123","mergeable":true}'
    exit 0
fi
if [[ "$args" == *"-X POST"* && "$args" == *"/api/v1/repos/mosaicstack/stack/pulls/123/merge"* ]]; then
    if [[ "$post_data" != '{"Do":"squash"}' ]]; then
        echo "unexpected merge payload: $post_data" >&2
        exit 96
    fi
    emit_response '{"merged":true,"message":"mock merge complete"}'
    exit 0
fi
echo "unexpected curl invocation: $*" >&2
exit 97
EOF
chmod +x "$MOCK_BIN/curl"

cd "$REPO_DIR"
git init -q
git remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git

export PATH="$MOCK_BIN:$PATH"
export PR_MERGE_TEST_LOG="$LOG_FILE"
export GITEA_LOGIN="git.mosaicstack.dev"
export GITEA_URL="https://git.mosaicstack.dev"
export GITEA_TOKEN="redacted-test-token"

OUTPUT="$SANDBOX/output.log"
if ! "$SCRIPT_DIR/pr-merge.sh" -n 123 -m squash --skip-queue-guard > "$OUTPUT" 2>&1; then
    echo "Expected pr-merge.sh to recover via Gitea API fallback." >&2
    echo "--- output ---" >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$OUTPUT" >&2
    echo "--- mock log ---" >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$LOG_FILE" >&2
    exit 1
fi

if ! grep -q '/api/v1/repos/mosaicstack/stack/pulls/123/merge' "$LOG_FILE"; then
    echo "Expected authenticated Gitea merge API endpoint to be called." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$LOG_FILE" >&2
    exit 1
fi

if grep -q 'redacted-test-token' "$OUTPUT"; then
    echo "Token leaked to pr-merge.sh output." >&2
    exit 1
fi

cat > "$MOCK_BIN/tea" <<'EOF'
#!/bin/bash
set -euo pipefail
printf 'tea %q ' "$@" >> "$PR_MERGE_TEST_LOG"
printf '\n' >> "$PR_MERGE_TEST_LOG"
if [[ "$*" == *"login list"* ]]; then
    echo '[{"name":"git.mosaicstack.dev","url":"https://git.mosaicstack.dev"}]'
    exit 0
fi
if [[ "$*" == *"pr merge"* ]]; then
    echo 'tea network timeout' >&2
    exit 2
fi
exit 0
EOF
chmod +x "$MOCK_BIN/tea"
: > "$LOG_FILE"
if "$SCRIPT_DIR/pr-merge.sh" -n 123 -m squash --skip-queue-guard > "$OUTPUT" 2>&1; then
    echo "Expected arbitrary tea failure to remain blocking." >&2
    exit 1
fi
if grep -q '/api/v1/repos/mosaicstack/stack/pulls/123/merge' "$LOG_FILE"; then
    echo "Arbitrary tea failure unexpectedly used Gitea API merge fallback." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$LOG_FILE" >&2
    exit 1
fi
if ! grep -q 'tea network timeout' "$OUTPUT"; then
    echo "Expected arbitrary tea error to be preserved in output." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$OUTPUT" >&2
    exit 1
fi

cat > "$MOCK_BIN/tea" <<'EOF'
#!/bin/bash
set -euo pipefail
printf 'tea %q ' "$@" >> "$PR_MERGE_TEST_LOG"
printf '\n' >> "$PR_MERGE_TEST_LOG"
if [[ "$*" == *"login list"* ]]; then
    echo '[]'
    exit 0
fi
if [[ "$*" == *"pr merge"* ]]; then
    echo 'tea merge should not run without a configured host login' >&2
    exit 99
fi
exit 0
EOF
chmod +x "$MOCK_BIN/tea"
unset GITEA_LOGIN
: > "$LOG_FILE"
if ! "$SCRIPT_DIR/pr-merge.sh" -n 123 -m squash --skip-queue-guard > "$OUTPUT" 2>&1; then
    echo "Expected missing tea login to use authenticated Gitea API fallback." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$OUTPUT" >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$LOG_FILE" >&2
    exit 1
fi
if ! grep -q '/api/v1/repos/mosaicstack/stack/pulls/123/merge' "$LOG_FILE"; then
    echo "Expected missing tea login path to call Gitea API merge endpoint." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$LOG_FILE" >&2
    exit 1
fi

SENTINEL="$SANDBOX/injected-sentinel"
INJECTION="123; touch $SENTINEL #"

cat > "$MOCK_BIN/gh" <<'EOF'
#!/bin/bash
set -euo pipefail
printf 'gh %q ' "$@" >> "$PR_MERGE_TEST_LOG"
printf '\n' >> "$PR_MERGE_TEST_LOG"
if [[ "$*" == *"pr view"* ]]; then
    cat <<'JSON'
{"number":123,"title":"mock","baseRefName":"main","headRefName":"feature/mock"}
JSON
    exit 0
fi
if [[ "$*" == *"pr merge"* ]]; then
    exit 0
fi
echo "unexpected gh invocation: $*" >&2
exit 98
EOF
chmod +x "$MOCK_BIN/gh"

cd "$REPO_DIR"
git remote set-url origin https://github.com/mosaicstack/stack.git
: > "$LOG_FILE"
rm -f "$SENTINEL"
if "$SCRIPT_DIR/pr-merge.sh" -n "$INJECTION" -m squash --skip-queue-guard > "$OUTPUT" 2>&1; then
    echo "Expected GitHub metacharacter PR number to be rejected." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$OUTPUT" >&2
    exit 1
fi
if [[ -e "$SENTINEL" ]]; then
    echo "GitHub metacharacter PR number executed injected shell command." >&2
    exit 1
fi
if [[ -s "$LOG_FILE" ]]; then
    echo "GitHub metacharacter PR number should be rejected before gh calls." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$LOG_FILE" >&2
    exit 1
fi
if ! grep -q 'Invalid PR number' "$OUTPUT"; then
    echo "Expected invalid PR number error for GitHub metacharacter input." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$OUTPUT" >&2
    exit 1
fi

cd "$REPO_DIR"
git remote set-url origin https://git.mosaicstack.dev/mosaicstack/stack.git
export GITEA_LOGIN="git.mosaicstack.dev"
: > "$LOG_FILE"
rm -f "$SENTINEL"
if "$SCRIPT_DIR/pr-merge.sh" -n "$INJECTION" -m squash --skip-queue-guard > "$OUTPUT" 2>&1; then
    echo "Expected Gitea metacharacter PR number to be rejected." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$OUTPUT" >&2
    exit 1
fi
if [[ -e "$SENTINEL" ]]; then
    echo "Gitea metacharacter PR number executed injected shell command." >&2
    exit 1
fi
if [[ -s "$LOG_FILE" ]]; then
    echo "Gitea metacharacter PR number should be rejected before tea/curl calls." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$LOG_FILE" >&2
    exit 1
fi
if ! grep -q 'Invalid PR number' "$OUTPUT"; then
    echo "Expected invalid PR number error for Gitea metacharacter input." >&2
    sed 's/redacted-test-token/***REDACTED***/g' "$OUTPUT" >&2
    exit 1
fi

echo "pr-merge.sh Gitea fallback regression passed"
