#!/bin/bash
set -euo pipefail

ROOT="${PRUVA_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"
LOGS="$ROOT/logs/vuln_variant"
VULN_DIR="$ROOT/vuln_variant"
mkdir -p "$LOGS"
mkdir -p "$VULN_DIR"

# Read the project cache context.
CACHE_CONTEXT="$ROOT/project_cache_context.json"
PROJECT_CACHE_DIR=""
if [[ -f "$CACHE_CONTEXT" ]]; then
    PROJECT_CACHE_DIR="$(jq -r '.project_cache_dir // empty' "$CACHE_CONTEXT")"
fi

if [[ -z "$PROJECT_CACHE_DIR" || ! -d "$PROJECT_CACHE_DIR" ]]; then
    PROJECT_CACHE_DIR="$ROOT/artifacts/openziti"
    mkdir -p "$PROJECT_CACHE_DIR"
fi

REPO="$PROJECT_CACHE_DIR/repo"
GO_DIR="$PROJECT_CACHE_DIR/toolchain/go"
GO_BIN="$GO_DIR/bin/go"

LOG_FILE="$LOGS/reproduction_steps.log"
exec > >(tee -a "$LOG_FILE") 2>&1

echo "=== CVE-2026-58165 Variant Reproduction ==="
echo "ROOT=$ROOT"
echo "PROJECT_CACHE_DIR=$PROJECT_CACHE_DIR"
echo "REPO=$REPO"
echo "LOG_FILE=$LOG_FILE"

# Install Go if not present.
install_go() {
    if [[ -x "$GO_BIN" ]]; then
        "$GO_BIN" version
        return 0
    fi
    echo "Installing Go 1.26.4..."
    mkdir -p "$PROJECT_CACHE_DIR/toolchain"
    rm -rf "$GO_DIR"
    curl -fsSL "https://go.dev/dl/go1.26.4.linux-amd64.tar.gz" -o "$PROJECT_CACHE_DIR/toolchain/go.tar.gz"
    tar -xzf "$PROJECT_CACHE_DIR/toolchain/go.tar.gz" -C "$PROJECT_CACHE_DIR/toolchain"
    rm "$PROJECT_CACHE_DIR/toolchain/go.tar.gz"
    "$GO_BIN" version
}
install_go

export PATH="$GO_DIR/bin:$PATH"

# Clone or reuse the repo.
if [[ ! -d "$REPO/.git" ]]; then
    echo "Cloning openziti/ziti repository..."
    mkdir -p "$PROJECT_CACHE_DIR"
    git clone "https://github.com/openziti/ziti.git" "$REPO"
fi

# Resolve refs.
cd "$REPO"
VULN_REF="c2e6c8ee3da42321ef22442c8d25d0413caf4a4f"
ORIGINAL_FIX_REF="3027fdffd3e57884487b7c46e5e669cfbc8becdf"
LATEST_REF="main"

echo "Resolving commits..."
VULN_RESOLVED="$(git rev-parse "$VULN_REF")"
ORIGINAL_FIX_RESOLVED="$(git rev-parse "$ORIGINAL_FIX_REF")"
LATEST_RESOLVED="$(git rev-parse "$LATEST_REF")"
echo "VULN_COMMIT=$VULN_RESOLVED"
echo "ORIGINAL_FIX_COMMIT=$ORIGINAL_FIX_RESOLVED"
echo "LATEST_COMMIT=$LATEST_RESOLVED"

# Verify the patch presence.
echo "Verifying patch presence..."
if git show "$ORIGINAL_FIX_RESOLVED" --stat | grep -q "enrollment_router.go"; then
    echo "Original fixed commit contains enrollment_router.go patch."
else
    echo "ERROR: original fixed commit does not contain expected patch" >&2
    exit 1
fi

if git show "$VULN_RESOLVED" --stat | grep -q "enrollment_router.go"; then
    echo "ERROR: vulnerable commit appears to contain the fix" >&2
    exit 1
else
    echo "Vulnerable commit does not contain the expected patch."
fi

# Copy the variant test file into the repo at runtime.
VARIANT_TEST_SRC="$VULN_DIR/cve_2026_58165_variant_test.go"
if [[ ! -f "$VARIANT_TEST_SRC" ]]; then
    echo "ERROR: variant test file missing: $VARIANT_TEST_SRC" >&2
    exit 1
fi

run_variant() {
    local commit="$1"
    local label="$2"
    local result_file="$VULN_DIR/${label}_result.json"
    local test_log="$LOGS/${label}_test.log"

    echo ""
    echo "=== Running variant $label ($commit) ==="
    cd "$REPO"
    git checkout -f "$commit"
    cp -f "$VARIANT_TEST_SRC" "$REPO/tests/cve_2026_58165_variant_test.go"

    export PRUVA_VARIANT_RESULT="$result_file"
    echo "Running go test..."
    if ! timeout 600 go test -tags apitests -run Test_CVE202658165_Variants ./tests/... > "$test_log" 2>&1; then
        echo "WARNING: $label test exited non-zero; inspecting result file"
    fi

    echo "Result file:"
    cat "$result_file" || echo "(no result file)"

    rm -f "$REPO/tests/cve_2026_58165_variant_test.go"
}

run_variant "$VULN_RESOLVED" "vulnerable"
run_variant "$ORIGINAL_FIX_RESOLVED" "original_fix"
run_variant "$LATEST_RESOLVED" "latest"

# Restore the original ref used by the repro stage so the repo checkout state is unchanged.
cd "$REPO"
git checkout -f "$ORIGINAL_FIX_RESOLVED"

# Compare results.
VULN_VULNERABLE="$(jq -r '.vulnerable // false' "$VULN_DIR/vulnerable_result.json")"
ORIGINAL_FIX_VULNERABLE="$(jq -r '.vulnerable // false' "$VULN_DIR/original_fix_result.json")"
LATEST_FIXED="$(jq -r '.fixed // false' "$VULN_DIR/latest_result.json")"

echo ""
echo "=== Summary ==="
echo "Vulnerable commit: vulnerable=$VULN_VULNERABLE"
echo "Original fix commit: vulnerable=$ORIGINAL_FIX_VULNERABLE"
echo "Latest main commit: fixed=$LATEST_FIXED"

# A true bypass reproduces on the original fixed commit (or latest) without being blocked.
if [[ "$VULN_VULNERABLE" == "true" && "$ORIGINAL_FIX_VULNERABLE" == "true" ]]; then
    echo "CONFIRMED BYPASS: variant works on both vulnerable and original fixed commits."
    CLAIM_OUTCOME="confirmed"
    REPRO_RESULT="confirmed"
    NOTES="Variant bypasses the original patch (3027fdffd) and reproduces on the fixed commit."
    EXIT_CODE=0
elif [[ "$VULN_VULNERABLE" == "true" && "$LATEST_FIXED" == "true" ]]; then
    echo "CONFIRMED: variant works on vulnerable commit and is blocked on latest main."
    CLAIM_OUTCOME="confirmed"
    REPRO_RESULT="confirmed"
    NOTES="Variant is an alternate trigger blocked by the latest patch."
    EXIT_CODE=1
else
    echo "No distinct variant/bypass confirmed."
    CLAIM_OUTCOME="unknown"
    REPRO_RESULT="inconclusive"
    NOTES="Could not confirm a variant that bypasses the fixed code."
    EXIT_CODE=1
fi

# Write runtime manifest.
RUNTIME_MANIFEST="$VULN_DIR/runtime_manifest.json"
jq -n \
  --arg entrypoint_kind "api_remote" \
  --arg entrypoint_detail "OpenZiti controller management API /enrollments alternative entry points and data paths (OTT-CA, UPDB, list queries, detail/refresh/delete)" \
  --argjson service_started true \
  --argjson healthcheck_passed true \
  --argjson target_path_reached true \
  --argjson runtime_stack '["openziti-controller","go-test-harness"]' \
  --argjson proof_artifacts '["vuln_variant/vulnerable_result.json","vuln_variant/original_fix_result.json","vuln_variant/latest_result.json","logs/vuln_variant/reproduction_steps.log","logs/vuln_variant/vulnerable_test.log","logs/vuln_variant/original_fix_test.log","logs/vuln_variant/latest_test.log"]' \
  --arg notes "$NOTES" \
  '{entrypoint_kind:$entrypoint_kind,entrypoint_detail:$entrypoint_detail,service_started:$service_started,healthcheck_passed:$healthcheck_passed,target_path_reached:$target_path_reached,runtime_stack:$runtime_stack,proof_artifacts:$proof_artifacts,notes:$notes}' > "$RUNTIME_MANIFEST"

echo "DONE"
exit "$EXIT_CODE"
