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

# ─────────────────────────────────────────────────────────────────────────────
# docker-test.sh — run tests or benchmarks inside a resource-constrained
#                  Docker container.
#
# Usage:
#   ./scripts/docker-test.sh [command] [options]
#
# Commands:
#   test    Run cargo tests (default)
#   bench   Run criterion benchmarks
#   check   Compile tests + benchmarks without running (fast gate)
#   load    Run load tests (ignored tests in load_test.rs)
#   server  Start the server for ad-hoc testing
#   build   Build the Docker images without running
#   clean   Remove built images and volumes
#
# Options:
#   --cpus <n>        CPU limit          (default: 2)
#   --memory <size>   Memory limit       (default: 1g)
#   --disk <size>     tmpfs disk size    (default: 256m)
#   --filter <name>   Test/bench filter  (default: all)
#   --threads <n>     Test threads       (default: auto)
#   --rebuild         Force rebuild images before running
#
# Examples:
#   ./scripts/docker-test.sh test --cpus 1 --memory 512m
#   ./scripts/docker-test.sh bench --cpus 4 --memory 4g --filter codec
#   ./scripts/docker-test.sh server --cpus 2 --memory 2g
# ─────────────────────────────────────────────────────────────────────────────

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
COMPOSE_FILE="$PROJECT_DIR/docker-compose.test.yml"

# Defaults
COMMAND="test"
export CPU_LIMIT="2"
export MEM_LIMIT="1g"
export DISK_SIZE="256m"
export TEST_FILTER=""
export BENCH_FILTER=""
export TEST_THREADS=""
REBUILD=""

usage() {
    sed -n '/^# Usage:/,/^# ──/p' "$0" | head -n -1 | sed 's/^# //' | sed 's/^#//'
    exit 0
}

# Parse arguments
while [[ $# -gt 0 ]]; do
    case "$1" in
        test|bench|check|load|server|build|clean)
            COMMAND="$1"; shift ;;
        --cpus)
            export CPU_LIMIT="$2"; shift 2 ;;
        --memory)
            export MEM_LIMIT="$2"; shift 2 ;;
        --disk)
            export DISK_SIZE="$2"; shift 2 ;;
        --filter)
            export TEST_FILTER="$2"
            export BENCH_FILTER="$2"
            shift 2 ;;
        --threads)
            export TEST_THREADS="$2"; shift 2 ;;
        --rebuild)
            REBUILD="--build"; shift ;;
        -h|--help)
            usage ;;
        *)
            echo "Unknown option: $1" >&2
            usage ;;
    esac
done

echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "  rust-fafb-q Docker test environment"
echo "  Command:  $COMMAND"
echo "  CPUs:     $CPU_LIMIT"
echo "  Memory:   $MEM_LIMIT"
echo "  Disk:     $DISK_SIZE"
[[ -n "$TEST_FILTER" ]] && echo "  Filter:   $TEST_FILTER"
[[ -n "$TEST_THREADS" ]] && echo "  Threads:  $TEST_THREADS"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

case "$COMMAND" in
    build)
        docker compose -f "$COMPOSE_FILE" build
        ;;
    clean)
        docker compose -f "$COMPOSE_FILE" down --rmi local --volumes --remove-orphans
        ;;
    load)
        docker compose -f "$COMPOSE_FILE" up $REBUILD --abort-on-container-exit "load_test"
        ;;
    check)
        # Quick compilation gate: compile tests + benchmarks without running.
        # Catches API drift between library code and bench/test binaries.
        docker compose -f "$COMPOSE_FILE" run --rm test \
            bash -c 'cargo test --release --no-run 2>&1 | tail -5 && cargo bench --no-run 2>&1 | tail -5 && echo "✓ all targets compile"'
        ;;
    test|bench|server)
        docker compose -f "$COMPOSE_FILE" up $REBUILD --abort-on-container-exit "$COMMAND"
        ;;
esac
