#!/usr/bin/env bash
set -euo pipefail

PACK_DIR=${PACK_DIR:-"$DEVENV_ROOT"}
PORT=${PORT:-8080}
IMAGE=${IMAGE:-itzg/minecraft-server:2026.8.0-java21}
CONTAINER=${CONTAINER:-aeroslop-itzg-test}
VOLUME=${VOLUME:-aeroslop-test-data}
MEMORY=${MEMORY:-4G}
BOOT_TIMEOUT=${BOOT_TIMEOUT:-600}
STOP_TIMEOUT=${STOP_TIMEOUT:-90}
CACHE_DIR=${PACK_TEST_CACHE:-"${XDG_CACHE_HOME:-$HOME/.cache}/aeroslop-pack-test"}

if [[ ! -f "$PACK_DIR/pack.toml" ]]; then
  echo "error: $PACK_DIR/pack.toml not found (set PACK_DIR)" >&2
  exit 1
fi

MC_VERSION=$(sed -n 's/^minecraft = "\(.*\)"$/\1/p' "$PACK_DIR/pack.toml")
NEOFORGE_VERSION=$(sed -n 's/^neoforge = "\(.*\)"$/\1/p' "$PACK_DIR/pack.toml")
if [[ -z "$MC_VERSION" || -z "$NEOFORGE_VERSION" ]]; then
  echo "error: could not read minecraft/neoforge versions from $PACK_DIR/pack.toml" >&2
  exit 1
fi

mkdir -p "$CACHE_DIR"
LOG="$CACHE_DIR/itzg-test.log"

cleanup() {
  set +e
  if [[ -n "${CONTAINER_ID:-}" ]]; then
    docker stop -t "$STOP_TIMEOUT" "$CONTAINER" >/dev/null 2>&1
  fi
  if [[ -n "${SERVE_PID:-}" ]]; then
    kill "$SERVE_PID" 2>/dev/null
    wait "$SERVE_PID" 2>/dev/null
  fi
}
trap cleanup EXIT

echo "== packwiz serve (port $PORT)"
(cd "$PACK_DIR" && exec packwiz serve --port "$PORT" >"$CACHE_DIR/serve.log" 2>&1) &
SERVE_PID=$!

for i in $(seq 1 30); do
  if curl -fs "http://127.0.0.1:$PORT/pack.toml" >/dev/null 2>&1; then
    break
  fi
  if ! kill -0 "$SERVE_PID" 2>/dev/null; then
    echo "error: packwiz serve failed:" >&2
    cat "$CACHE_DIR/serve.log" >&2
    exit 1
  fi
  sleep 1
done
if ! curl -fs "http://127.0.0.1:$PORT/pack.toml" -o "$CACHE_DIR/served-pack.toml" 2>/dev/null; then
  echo "error: packwiz serve did not come up" >&2
  exit 1
fi
if ! cmp -s "$CACHE_DIR/served-pack.toml" "$PACK_DIR/pack.toml"; then
  echo "error: port $PORT is serving a different pack (stale serve process?)" >&2
  exit 1
fi

echo "== starting itzg container ($IMAGE)"
docker rm -f "$CONTAINER" >/dev/null 2>&1 || true
CONTAINER_ID=$(docker run -d --name "$CONTAINER" \
  --network host \
  -e EULA=TRUE \
  -e TYPE=NEOFORGE \
  -e VERSION="$MC_VERSION" \
  -e NEOFORGE_VERSION="$NEOFORGE_VERSION" \
  -e MEMORY="$MEMORY" \
  -e LEVEL_TYPE=FLAT \
  -e PACKWIZ_URL="http://127.0.0.1:$PORT/pack.toml" \
  -v "$VOLUME":/data \
  "$IMAGE")

docker logs -f "$CONTAINER" >"$LOG" 2>&1 &
LOGS_PID=$!

echo "== waiting for server boot (up to ${BOOT_TIMEOUT}s)"
deadline=$((SECONDS + BOOT_TIMEOUT))
while (( SECONDS < deadline )); do
  if ! docker inspect -f '{{.State.Running}}' "$CONTAINER" 2>/dev/null | grep -q true; then
    echo "error: container exited before boot completed" >&2
    tail -50 "$LOG" >&2 || true
    exit 1
  fi
  if grep -q "Done (" "$LOG" 2>/dev/null; then
    break
  fi
  sleep 5
done

if ! grep -q "Done (" "$LOG" 2>/dev/null; then
  echo "error: server did not reach 'Done' within ${BOOT_TIMEOUT}s" >&2
  tail -50 "$LOG" >&2 || true
  exit 1
fi

echo "== server booted; stopping gracefully"
docker stop -t "$STOP_TIMEOUT" "$CONTAINER" >/dev/null

if grep -Eq "FATAL|Exception in thread|crash report|Failed to start" "$LOG"; then
  echo "error: fatal lines in server log:" >&2
  grep -E "FATAL|Exception in thread|crash report|Failed to start" "$LOG" >&2 || true
  exit 1
fi

echo "== PASS: server booted with pack (mc=$MC_VERSION, neoforge=$NEOFORGE_VERSION)"
