# Multi-stage Dockerfile for socktop webterm
# This reduces the final image size significantly by separating build and runtime

# ============================================================================
# Stage 1: Documentation Builder
# ============================================================================
FROM rust:1.95-slim-bookworm AS docs-builder

WORKDIR /build

# Install required tools
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# Install mdbook first
RUN cargo install mdbook

# Copy documentation source (includes theme files)
COPY docs ./docs

# Download Catppuccin theme CSS if not already present
RUN if [ ! -f docs/theme/catppuccin.css ]; then \
    curl -fsSL https://github.com/catppuccin/mdBook/releases/latest/download/catppuccin.css \
    -o docs/theme/catppuccin.css && \
    echo "Catppuccin CSS downloaded successfully"; \
    else \
    echo "Catppuccin CSS already present"; \
    fi

# Build documentation
RUN cd docs && \
    mdbook build && \
    ls -la book/

# ============================================================================
# Stage 2: Rust Builder
# ============================================================================
FROM rust:1.95-slim-bookworm AS rust-builder

WORKDIR /build

# Install build dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    pkg-config \
    libssl-dev \
    && rm -rf /var/lib/apt/lists/*

# Copy only dependency files first for better caching
COPY Cargo.toml Cargo.lock ./

# Create dummy source to cache dependencies
RUN mkdir src && \
    echo "fn main() {}" > src/server.rs && \
    echo "pub fn lib() {}" > src/lib.rs && \
    cargo build --release && \
    rm -rf src target/release/webterm-server target/release/deps/webterm*

# Copy actual source code
COPY src ./src
COPY templates ./templates
COPY static ./static
COPY build.rs ./build.rs

# Copy built documentation from docs-builder stage
COPY --from=docs-builder /build/docs/book ./static/docs

# Verify documentation was copied
RUN ls -la ./static/docs/ && \
    test -f ./static/docs/index.html || (echo "ERROR: Documentation index.html not found!" && exit 1)

# Build the actual application (force rebuild by touching sources)
RUN touch src/server.rs src/lib.rs && \
    cargo build --release && \
    strip target/release/webterm-server

# ============================================================================
# Stage 3: Node.js Builder
# ============================================================================
FROM node:20-slim AS node-builder

WORKDIR /build

# Copy package files
COPY package.json package-lock.json ./
COPY static ./static

# Install only production dependencies
RUN npm ci --only=production && \
    # Copy static files to node_modules for serving
    cp static/terminado-addon.js node_modules/ && \
    cp static/bg.png node_modules/ && \
    cp static/styles.css node_modules/ && \
    cp static/terminal.js node_modules/ && \
    cp static/favicon.png node_modules/

# ============================================================================
# Stage 4: Runtime Image
# ============================================================================
FROM debian:trixie-slim

# Avoid prompts from apt
ENV DEBIAN_FRONTEND=noninteractive
ENV TERM=xterm-256color

# Install only runtime dependencies
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y --no-install-recommends \
    # Runtime libraries
    libssl3 \
    ca-certificates \
    # For socktop packages
    curl \
    gnupg2 \
    # Shell and utilities
    bash \
    procps \
    # Health check
    curl \
    && rm -rf /var/lib/apt/lists/*

# Add socktop APT repository and install packages
RUN curl -fsSL https://jasonwitty.github.io/socktop/KEY.gpg | \
    gpg --dearmor -o /usr/share/keyrings/socktop-archive-keyring.gpg && \
    echo "deb [signed-by=/usr/share/keyrings/socktop-archive-keyring.gpg] https://jasonwitty.github.io/socktop stable main" > /etc/apt/sources.list.d/socktop.list && \
    apt-get update && \
    apt-get install -y --no-install-recommends socktop socktop-agent && \
    rm -rf /var/lib/apt/lists/*

# Create application user (if not already exists from socktop packages)
RUN id -u socktop &>/dev/null || useradd -m -s /bin/bash socktop && \
    mkdir -p /home/socktop/.config/socktop && \
    chown -R socktop:socktop /home/socktop

# Set working directory
WORKDIR /app

# Copy built binary from rust-builder
COPY --from=rust-builder /build/target/release/webterm-server /usr/local/bin/webterm-server

# Copy templates and static files
COPY --from=rust-builder /build/templates ./templates
COPY --from=rust-builder /build/static ./static

# Verify documentation is present in static/docs
RUN ls -la ./static/docs/ && \
    test -f ./static/docs/index.html || echo "WARNING: Documentation not found in static/docs"

# Copy node_modules from node-builder
COPY --from=node-builder /build/node_modules ./node_modules

# Copy runtime scripts
COPY docker/entrypoint.sh /entrypoint.sh
COPY docker/init-config.sh /init-config.sh
COPY docker/restricted-shell.sh /usr/local/bin/restricted-shell.sh
RUN chmod +x /entrypoint.sh /init-config.sh /usr/local/bin/restricted-shell.sh

# Expose ports
# 8082 - webterm HTTP server
# 3001 - socktop agent (if used)
EXPOSE 8082 3001

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:8082/ || exit 1

# Create a wrapper script that detects if running as root or socktop user
RUN echo '#!/bin/bash\n\
    if [ "$(id -u)" -eq 0 ]; then\n\
    # Running as root - use init-config.sh to set up and switch to socktop\n\
    exec /init-config.sh "$@"\n\
    else\n\
    # Running as socktop user - directly execute entrypoint\n\
    exec /entrypoint.sh "$@"\n\
    fi' > /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh

# Set entrypoint to the wrapper
ENTRYPOINT ["/docker-entrypoint.sh"]

# Default command - use restricted shell that only allows socktop commands
CMD ["webterm-server", "--host", "0.0.0.0", "--port", "8082", "--command", "/usr/local/bin/restricted-shell.sh"]
