#!/bin/bash
set -euo pipefail

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

cd "$ROOT"

FIX_IMAGE="registry.cn-qingdao.aliyuncs.com/dataease/dataease:v2.10.21"
MYSQL_IMAGE="registry.cn-qingdao.aliyuncs.com/dataease/mysql:8.4.5"

# Cleanup function
cleanup() {
    echo "[*] Cleaning up..."
    docker rm -f dataease-fix-variant mysql-fix-variant 2>/dev/null || true
    docker network rm de-net-fix-variant 2>/dev/null || true
    rm -rf /tmp/dataease-repro-fix-variant
}
trap cleanup EXIT

# Pre-clean
docker rm -f dataease-fix-variant mysql-fix-variant 2>/dev/null || true
docker network rm de-net-fix-variant 2>/dev/null || true
sleep 2

# Find a free port
FIX_PORT=$(python3 -c "import socket; s=socket.socket(); s.bind(('',0)); p=s.getsockname()[1]; s.close(); print(p)")
echo "[*] Using port $FIX_PORT for fixed version"

# Write variant test Python script
VARIANT_PY="$LOGS/variant_test_fix.py"
cat > "$VARIANT_PY" <<'PY'
import base64, json, urllib.request, sys

port = sys.argv[1]
variant = sys.argv[2]
url = f"http://127.0.0.1:{port}/de2api/datasource/validate"

configs = {
    "original": {"type":"mysql","host":"127.0.0.1","port":3306,"dataBase":"test","extraParams":"allowloadlocalinfile=true","illegalParameters":[]},
    "mariadb": {"type":"mariadb","host":"127.0.0.1","port":3306,"dataBase":"test","extraParams":"allowloadlocalinfile=true","illegalParameters":[]},
    "direct_jdbcurl": {"type":"mysql","urlType":"jdbcUrl","jdbcUrl":"jdbc:mysql://127.0.0.1:3306/test?allowloadlocalinfile=true","extraParams":"","illegalParameters":[]},
    "double_encode": {"type":"mysql","host":"127.0.0.1","port":3306,"dataBase":"test","extraParams":"%2561llowloadlocalinfile=true","illegalParameters":[]},
    "case_mixed": {"type":"mysql","host":"127.0.0.1","port":3306,"dataBase":"test","extraParams":"ALLOWLOADLOCALINFILE=true","illegalParameters":[]},
    "parent_field": {"type":"mysql","host":"127.0.0.1","port":3306,"dataBase":"test","extraParams":"allowloadlocalinfile=true","IllegalParameters":[]},
    "oracle": {"type":"oracle","host":"127.0.0.1","port":1521,"dataBase":"test","extraParams":"autoDeserialize=true","illegalParameters":[]},
    "pg": {"type":"pg","host":"127.0.0.1","port":5432,"dataBase":"test","extraParams":"socketFactory=java.lang.Runtime","illegalParameters":[]},
}

malicious_config = configs.get(variant, configs["original"])
payload = {
    "type": malicious_config.get("type", "mysql"),
    "name": f"evil-ds-{variant}",
    "nodeType": "datasource",
    "action": "validate",
    "configuration": base64.b64encode(json.dumps(malicious_config).encode()).decode()
}

req = urllib.request.Request(url, data=json.dumps(payload).encode(), headers={"Content-Type": "application/json"}, method="POST")
try:
    with urllib.request.urlopen(req, timeout=15) as resp:
        body = resp.read().decode()
        print(body)
except urllib.error.HTTPError as e:
    body = e.read().decode()
    print(body)
except Exception as e:
    print(json.dumps({"error": str(e)}))
PY

# Setup directories
BASE_DIR="/tmp/dataease-repro-fix-variant"
rm -rf "$BASE_DIR"
mkdir -p "$BASE_DIR/bin/mysql" "$BASE_DIR/data/mysql" "$BASE_DIR/logs" \
         "$BASE_DIR/data/static-resource" "$BASE_DIR/data/geo" \
         "$BASE_DIR/data/appearance" "$BASE_DIR/data/exportData" \
         "$BASE_DIR/data/plugin" "$BASE_DIR/data/font" "$BASE_DIR/data/i18n"

cat > "$BASE_DIR/bin/mysql/init.sql" <<'EOF'
CREATE DATABASE IF NOT EXISTS `dataease` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
EOF

cat > "$BASE_DIR/my.cnf" <<'EOF'
[mysqld]
default-storage-engine=INNODB
character_set_server=utf8mb4
max_connections=2000
innodb_flush_log_at_trx_commit=0
sync_binlog=0
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
skip-name-resolve
EOF

cat > "$BASE_DIR/application.yml" <<EOF
server:
  tomcat:
    connection-timeout: 70000
spring:
  servlet:
    multipart:
      max-file-size: 500MB
      max-request-size: 500MB
  datasource:
    url: jdbc:mysql://mysql-fix-variant:3306/dataease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: Password123@mysql
dataease:
  origin-list: "http://localhost:8100"
  login_timeout: 960
task:
  executor:
    address: http://sync-task-actuator:9001
    log:
      path: /opt/dataease2.0/logs/sync-task/task-handler-log
EOF

cat > "$BASE_DIR/compose.yml" <<EOF
services:
  mysql-fix-variant:
    image: ${MYSQL_IMAGE}
    container_name: mysql-fix-variant
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-pPassword123@mysql", "--protocol", "tcp"]
      interval: 5s
      timeout: 3s
      retries: 20
    environment:
      MYSQL_ROOT_PASSWORD: Password123@mysql
    volumes:
      - ${BASE_DIR}/my.cnf:/etc/mysql/conf.d/my.cnf
      - ${BASE_DIR}/bin/mysql:/docker-entrypoint-initdb.d/
      - ${BASE_DIR}/data/mysql:/var/lib/mysql
    networks:
      - de-net-fix-variant

  dataease-fix-variant:
    image: ${FIX_IMAGE}
    container_name: dataease-fix-variant
    ports:
      - "${FIX_PORT}:8100"
    depends_on:
      mysql-fix-variant:
        condition: service_healthy
    networks:
      - de-net-fix-variant
    environment:
      - SPRING_PROFILES_ACTIVE=standalone
    volumes:
      - ${BASE_DIR}/application.yml:/opt/dataease2.0/conf/application.yml
      - ${BASE_DIR}/logs:/opt/dataease2.0/logs
      - ${BASE_DIR}/data/static-resource:/opt/dataease2.0/data/static-resource
      - ${BASE_DIR}/data/geo:/opt/dataease2.0/data/geo
      - ${BASE_DIR}/data/appearance:/opt/dataease2.0/data/appearance
      - ${BASE_DIR}/data/exportData:/opt/dataease2.0/data/exportData
      - ${BASE_DIR}/data/plugin:/opt/dataease2.0/data/plugin
      - ${BASE_DIR}/data/font:/opt/dataease2.0/data/font
      - ${BASE_DIR}/data/i18n:/opt/dataease2.0/data/i18n

networks:
  de-net-fix-variant:
    name: de-net-fix-variant
EOF

cd "$BASE_DIR"
docker compose -f compose.yml up -d
cd "$ROOT"

# Wait for DataEase
echo "[*] Waiting for DataEase fixed version on port $FIX_PORT..."
for i in $(seq 1 180); do
    if curl -sf "http://127.0.0.1:${FIX_PORT}/de2api/datasource/types" >/dev/null 2>&1; then
        echo "[*] DataEase fixed version is responding on port $FIX_PORT"
        break
    fi
    if ! docker ps -q -f "name=dataease-fix-variant" | grep -q .; then
        echo "[ERROR] Container stopped unexpectedly"
        docker logs dataease-fix-variant > "$LOGS/dataease-fix-variant_startup.log" 2>&1 || true
        exit 1
    fi
    sleep 3
done

if ! curl -sf "http://127.0.0.1:${FIX_PORT}/de2api/datasource/types" >/dev/null 2>&1; then
    echo "[ERROR] Timeout waiting for DataEase"
    docker logs dataease-fix-variant > "$LOGS/dataease-fix-variant_startup.log" 2>&1 || true
    exit 1
fi

# Run variant tests
for variant in original mariadb direct_jdbcurl double_encode case_mixed parent_field oracle pg; do
    echo ""
    echo "=== Testing variant: $variant ==="
    python3 "$VARIANT_PY" "$FIX_PORT" "$variant" 2>&1 | tee "$LOGS/fix_variant_${variant}.json" || true
    if grep -q "Illegal parameter" "$LOGS/fix_variant_${variant}.json" 2>/dev/null; then
        echo "[BLOCKED] Variant $variant was correctly blocked."
    elif grep -q "Communications link failure" "$LOGS/fix_variant_${variant}.json" 2>/dev/null; then
        echo "[BYPASS] Variant $variant bypassed the fix!"
        echo "$variant" >> "$LOGS/bypassed_variants.txt"
    else
        echo "[UNKNOWN] Unexpected response for variant $variant."
    fi
done

echo ""
echo "[*] Variant tests completed."
if [ -f "$LOGS/bypassed_variants.txt" ]; then
    echo "[!] Bypassed variants: $(cat "$LOGS/bypassed_variants.txt" | tr '\n' ' ')"
    exit 0
else
    echo "[*] No variants bypassed the fix."
    exit 1
fi
