#!/usr/bin/env bash
# =============================================================================
# SkillMeat Compose Wrapper
# =============================================================================
# Auto-detects Docker or Podman and runs the appropriate compose command.
#
# Usage:
#   ./compose.sh --profile local up -d
#   ./compose.sh --profile enterprise up -d
#   ./compose.sh --dev --profile enterprise up     # Dev mode (hot reload)
#   ./compose.sh --dev --profile local up           # Dev mode (local)
#   ./compose.sh down
#
# Flags:
#   --dev   Include docker-compose.dev.yml overlay (volume mounts + hot reload)
#
# Environment:
#   COMPOSE_ENGINE=docker|podman   Override auto-detection
# =============================================================================
set -euo pipefail

# ── Auto-detect container runtime ──────────────────────────────────────────

detect_engine() {
    # Honour explicit override
    if [ -n "${COMPOSE_ENGINE:-}" ]; then
        echo "$COMPOSE_ENGINE"
        return
    fi

    # Check for Podman first — on systems where `docker` is a podman shim
    # (e.g., Fedora, RHEL), detect the shim and use podman directly.
    # Note: the version check uses a variable to avoid SIGPIPE (exit 141)
    # when grep -q exits early under pipefail.
    if command -v podman &>/dev/null; then
        if command -v docker &>/dev/null; then
            local docker_ver
            docker_ver="$(docker --version 2>&1 || true)"
            if echo "$docker_ver" | grep -qi podman; then
                echo "podman"
                return
            fi
        fi
    fi

    # Prefer real Docker if available and daemon is reachable
    if command -v docker &>/dev/null; then
        if docker info &>/dev/null 2>&1; then
            echo "docker"
            return
        fi
    fi

    # Fall back to Podman
    if command -v podman &>/dev/null; then
        echo "podman"
        return
    fi

    echo >&2 "ERROR: Neither Docker nor Podman found. Install one of them first."
    exit 1
}

ENGINE=$(detect_engine)

# ── Parse --dev flag ──────────────────────────────────────────────────────
# Strip --dev from args and inject the dev overlay compose file.

DEV_MODE=false
ARGS=()
for arg in "$@"; do
    if [ "$arg" = "--dev" ]; then
        DEV_MODE=true
    else
        ARGS+=("$arg")
    fi
done
set -- "${ARGS[@]}"

if [ "$DEV_MODE" = true ]; then
    echo "[compose.sh] Dev mode enabled: mounting source for hot reload"
    set -- -f docker-compose.yml -f docker-compose.dev.yml "$@"
fi

# ── Resolve compose command ────────────────────────────────────────────────

resolve_compose() {
    local engine="$1"

    if [ "$engine" = "podman" ]; then
        # Ensure Podman socket is exposed for compose compatibility
        if [ -z "${DOCKER_HOST:-}" ]; then
            local sock="/run/user/$(id -u)/podman/podman.sock"
            if [ -S "$sock" ]; then
                export DOCKER_HOST="unix://$sock"
            else
                echo >&2 "WARN: Podman socket not found at $sock"
                echo >&2 "      Run: systemctl --user enable --now podman.socket"
            fi
        fi

        # Prefer 'podman compose' (v2-compatible, ships with Podman 4.7+)
        if podman compose version &>/dev/null 2>&1; then
            echo "podman compose"
            return
        fi

        # Fall back to standalone podman-compose
        if command -v podman-compose &>/dev/null; then
            echo "podman-compose"
            return
        fi

        echo >&2 "ERROR: Podman detected but no compose plugin found."
        echo >&2 "       Install one of:"
        echo >&2 "         - podman compose (built-in since Podman 4.7)"
        echo >&2 "         - pip install podman-compose"
        exit 1
    fi

    # Docker: prefer v2 plugin, fall back to standalone
    if docker compose version &>/dev/null 2>&1; then
        echo "docker compose"
    elif command -v docker-compose &>/dev/null; then
        echo "docker-compose"
    else
        echo >&2 "ERROR: Docker detected but no compose command found."
        echo >&2 "       Install Docker Compose: https://docs.docker.com/compose/install/"
        exit 1
    fi
}

COMPOSE_CMD=$(resolve_compose "$ENGINE")

echo "[compose.sh] Using: $COMPOSE_CMD (engine: $ENGINE)"

# ── Podman build workarounds ─────────────────────────────────────────────

if [ "$ENGINE" = "podman" ]; then
    # podman-compose doesn't pass --ulimit to podman build, so we
    # pre-build any services that have a build context, then let
    # compose do the rest (start/pull only).
    export BUILDAH_ULIMIT="nofile=65536:65536"

    # Check if this is an "up --build" or "build" invocation
    NEEDS_PREBUILD=false
    for arg in "$@"; do
        case "$arg" in
            --build|build) NEEDS_PREBUILD=true ;;
        esac
    done

    if [ "$NEEDS_PREBUILD" = true ]; then
        # Extract NEXT_PUBLIC_ build args from .env (safe grep, not full source)
        if [ -f .env ] && [ -z "${NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:-}" ]; then
            NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=$(grep -E '^NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=' .env | cut -d= -f2- | tr -d '"' | tr -d "'" || true)
            export NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
        fi
        echo "[compose.sh] Pre-building images with Podman (--ulimit nofile=65536:65536)..."

        # Use explicit image tags that match docker-compose.yml image: directives.
        # This ensures pre-built images are used regardless of project directory name
        # and avoids compose's auto-generated naming (project_service vs project-service).

        # Build skillmeat-api (root context)
        if [ -f Dockerfile ]; then
            echo "[compose.sh]   Building skillmeat-api:local..."
            podman build --ulimit nofile=65536:65536 \
                --format docker \
                -t "skillmeat-api:local" \
                -f Dockerfile .
        fi

        # Build skillmeat-web (web context)
        if [ -f skillmeat/web/Dockerfile ]; then
            WEB_TARGET_ARGS=""
            if [ "$DEV_MODE" = true ]; then
                WEB_TARGET_ARGS="--target dev"
                echo "[compose.sh]   Building skillmeat-web:local (dev target)..."
            else
                echo "[compose.sh]   Building skillmeat-web:local..."
            fi
            podman build --ulimit nofile=65536:65536 \
                --format docker \
                $WEB_TARGET_ARGS \
                --build-arg "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=${NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:-}" \
                -t "skillmeat-web:local" \
                -f skillmeat/web/Dockerfile skillmeat/web
        fi

        # Build skillmeat-docs (docs context)
        if [ -f Dockerfile.docs ]; then
            echo "[compose.sh]   Building skillmeat-docs:local..."
            podman build --ulimit nofile=65536:65536 \
                --format docker \
                -t "skillmeat-docs:local" \
                -f Dockerfile.docs .
        fi

        # Build backstage (demo context)
        if [ -f demo/backstage-app/package.json ] && [ -f demo/dockerfile ]; then
            echo "[compose.sh]   Building skillmeat-backstage:local..."
            podman build --ulimit nofile=65536:65536 \
                --format docker \
                -t "skillmeat-backstage:local" \
                -f demo/dockerfile demo/backstage-app
        fi

        echo "[compose.sh] Pre-build complete. Starting services..."

        # Strip --build from args so compose doesn't re-build
        FILTERED_ARGS=()
        for arg in "$@"; do
            [ "$arg" != "--build" ] && FILTERED_ARGS+=("$arg")
        done
        set -- "${FILTERED_ARGS[@]}"
    fi
fi

# ── Execute ────────────────────────────────────────────────────────────────

# shellcheck disable=SC2086
exec $COMPOSE_CMD "$@"
