# Huskies – single-container runtime
# All components (server, agents, web UI) run inside this container.
# The target project repo is bind-mounted at /workspace.
#
# Build:   docker build -t huskies -f docker/Dockerfile .
# Run:     docker compose -f docker/docker-compose.yml up
#
# Tested with: OrbStack (recommended on macOS), Docker Desktop (slower bind mounts)

FROM rust:1.90-bookworm AS base

# Clippy is needed at runtime for acceptance gates (cargo clippy)
RUN rustup component add clippy

# ── System deps ──────────────────────────────────────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
        git \
        curl \
        ca-certificates \
        build-essential \
        pkg-config \
        libssl-dev \
        # cargo-nextest is a pre-built binary
    && rm -rf /var/lib/apt/lists/*

# ── Node.js 22.x (matches host) ─────────────────────────────────────
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
    && apt-get install -y --no-install-recommends nodejs \
    && rm -rf /var/lib/apt/lists/*

# ── cargo-nextest (test runner) ──────────────────────────────────────
RUN curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C /usr/local/bin

# ── Claude Code CLI ──────────────────────────────────────────────────
# Claude Code is distributed as an npm global package.
# The CLI binary is `claude`.
RUN npm install -g @anthropic-ai/claude-code

# ── Working directory ────────────────────────────────────────────────
# /app holds the huskies source (copied in at build time for the binary).
# /workspace is where the target project repo gets bind-mounted at runtime.
WORKDIR /app

# ── Build the huskies server binary ─────────────────────────────────
# Copy the full project tree so `cargo build` and `npm run build` (via
# build.rs) can produce the release binary with embedded frontend assets.
COPY . .

# Build frontend deps first (better layer caching)
RUN cd frontend && npm ci

# Build the release binary (build.rs runs npm run build for the frontend)
RUN cargo build --release \
    && cp target/release/huskies /usr/local/bin/huskies

# ── Runtime stage (smaller image) ───────────────────────────────────
FROM debian:bookworm-slim AS runtime

RUN apt-get update && apt-get install -y --no-install-recommends \
        git \
        curl \
        ca-certificates \
        libssl3 \
        # build-essential (gcc/cc) needed at runtime for:
        # - rebuild_and_restart (cargo build --release)
        # - agent-driven cargo commands (clippy, test, build)
        build-essential \
        pkg-config \
        libssl-dev \
        # procps provides ps, needed by tests and process management
        procps \
    && rm -rf /var/lib/apt/lists/*

# Node.js in runtime
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
    && apt-get install -y --no-install-recommends nodejs \
    && rm -rf /var/lib/apt/lists/*

# Claude Code CLI in runtime
RUN npm install -g @anthropic-ai/claude-code

# Cargo and Rust toolchain needed at runtime for:
# - rebuild_and_restart (cargo build inside the container)
# - Agent-driven cargo commands (cargo clippy, cargo test, etc.)
COPY --from=base /usr/local/cargo /usr/local/cargo
COPY --from=base /usr/local/rustup /usr/local/rustup
ENV PATH="/usr/local/cargo/bin:${PATH}"
ENV RUSTUP_HOME="/usr/local/rustup"
ENV CARGO_HOME="/usr/local/cargo"

# cargo-nextest
COPY --from=base /usr/local/bin/cargo-nextest /usr/local/bin/cargo-nextest

# The huskies binary
COPY --from=base /usr/local/bin/huskies /usr/local/bin/huskies

# Copy the full source tree so rebuild_and_restart can do `cargo build`
# from the workspace root (CARGO_MANIFEST_DIR is baked into the binary).
# Alternative: mount the source as a volume.
COPY --from=base /app /app

# ── Non-root user ────────────────────────────────────────────────────
# Claude Code refuses --dangerously-skip-permissions (bypassPermissions)
# when running as root. Create a dedicated user so agents can launch.
RUN groupadd -r huskies \
    && useradd -r -g huskies -m -d /home/huskies huskies \
    && mkdir -p /home/huskies/.claude \
    && chown -R huskies:huskies /home/huskies \
    && chown -R huskies:huskies /usr/local/cargo /usr/local/rustup \
    && chown -R huskies:huskies /app \
    && mkdir -p /workspace/target /app/target \
    && chown huskies:huskies /workspace/target /app/target

# ── Entrypoint ───────────────────────────────────────────────────────
# Validates required env vars (GIT_USER_NAME, GIT_USER_EMAIL) and
# configures git identity before starting the server.
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh

USER huskies
WORKDIR /workspace

# ── Ports ────────────────────────────────────────────────────────────
# Web UI + MCP server
EXPOSE 3001

# ── Volumes (defined in docker-compose.yml) ──────────────────────────
# /workspace                    – bind mount: target project repo
# /home/huskies/.claude         – named volume: Claude Code sessions/state
# /usr/local/cargo/registry     – named volume: cargo dependency cache

ENTRYPOINT ["entrypoint.sh"]
CMD ["huskies", "/workspace"]
