# ---------- Stage 0: Go toolchain (for github-mcp-server STDIO) ----------
FROM golang:1.26.2-bookworm AS golang

# ---------- Stage 1: Build dependencies ----------
FROM python:3.13-slim AS builder

# Install system dependencies and uv in one layer
RUN apt-get update && apt-get upgrade -y --no-install-recommends \
    && apt-get install -y --no-install-recommends \
    gcc \
    git \
    && pip install uv \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Copy the entire project structure first since uv sync needs it to build
COPY --chown=root:root . /app/

# Install dependencies into venv (no dev deps) using committed lock file
# --locked ensures we use the existing uv.lock without modification
# Increase timeout for large packages (e.g., pyarrow 39MB)
RUN --mount=type=cache,target=/root/.cache/uv \
    UV_HTTP_TIMEOUT=300 uv sync --locked --no-dev

# Patch langchain_aws ChatBedrock._as_converse to forward base_model_id to
# ChatBedrockConverse. Without this, switching to the Converse API (e.g. when
# beta_use_converse_api=True) creates a new ChatBedrockConverse without base_model_id,
# triggering a GetInferenceProfile API call that fails when the IAM role only
# grants bedrock:InvokeModel / bedrock-runtime:Converse on the AIP ARN.
# Remove this patch once langchain-aws fixes _as_converse to forward base_model_id.
RUN BEDROCK_PY=".venv/lib/python3.13/site-packages/langchain_aws/chat_models/bedrock.py" && \
    grep -q 'guardrail_config=(self.guardrails if self._guardrails_enabled else None),  # type: ignore\[call-arg\]' "$BEDROCK_PY" || \
        { echo "ERROR: langchain_aws patch target not found — upstream may have changed. Review build/Dockerfile patch."; exit 1; } && \
    sed -i 's/guardrail_config=(self.guardrails if self._guardrails_enabled else None),  # type: ignore\[call-arg\]/guardrail_config=(self.guardrails if self._guardrails_enabled else None),  # type: ignore[call-arg]\n            base_model_id=self.base_model_id,/' "$BEDROCK_PY" && \
    grep -q 'base_model_id=self.base_model_id,' "$BEDROCK_PY" || \
        { echo "ERROR: langchain_aws patch was not applied — sed substitution had no effect."; exit 1; }

# ---------- Stage 2: Final runtime image ----------
# Wolfi (Chainguard) base: 0 CVEs, continuously patched packages.
FROM cgr.dev/chainguard/wolfi-base

# Override APK repo to public Wolfi OS packages (no auth required).
RUN echo "https://packages.wolfi.dev/os" > /etc/apk/repositories

# Install runtime dependencies. shadow provides groupadd/useradd.
RUN for i in 1 2 3; do \
        apk add --no-cache python-3.13 git wget curl grep unzip bash shadow && break; \
        [ $i -lt 3 ] && sleep $((i * 10)); \
    done && \
    apk upgrade --no-cache

# Use the official uv binary (astral-sh) — the Wolfi apk uv package bundles
# outdated Rust crates (rand, rustls-webpki) with known CVEs.
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

# The builder stage uses python:3.13-slim which places Python at
# /usr/local/bin/python3.13; Wolfi places it at /usr/bin/python3.13.
# These symlinks keep the venv's internal python symlinks from breaking.
RUN mkdir -p /usr/local/bin \
    && ln -sf /usr/bin/python3.13 /usr/local/bin/python3.13 \
    && ln -sf /usr/bin/python3.13 /usr/local/bin/python3 \
    && ln -sf /usr/bin/python3.13 /usr/local/bin/python

# AWS CLI v2 — used by aws_cli_execute tool in single-node AWS subagent
RUN ARCH=$(uname -m) && \
    if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then \
        curl -sfL --retry 5 --retry-delay 3 "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"; \
    else \
        curl -sfL --retry 5 --retry-delay 3 "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"; \
    fi && \
    unzip -q awscliv2.zip && \
    ./aws/install && \
    rm -rf awscliv2.zip aws

# kubectl — used by eks_kubectl_execute tool in single-node AWS subagent
RUN ARCH=$(uname -m) && \
    if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then \
        KUBECTL_ARCH="arm64"; \
    else \
        KUBECTL_ARCH="amd64"; \
    fi && \
    KUBECTL_VERSION=$(curl -sfL --retry 5 --retry-delay 3 https://dl.k8s.io/release/stable.txt) && \
    if [ -z "$KUBECTL_VERSION" ]; then echo "Failed to fetch kubectl version"; exit 1; fi && \
    curl -sfLO --retry 5 --retry-delay 3 "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${KUBECTL_ARCH}/kubectl" && \
    chmod +x kubectl && \
    mv kubectl /usr/local/bin/kubectl

# Terraform CLI — used by terraform_fmt tool for HCL formatting in self-service tasks
RUN ARCH=$(uname -m) && \
    if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then ARCH="arm64"; else ARCH="amd64"; fi && \
    wget -q "https://releases.hashicorp.com/terraform/1.14.8/terraform_1.14.8_linux_${ARCH}.zip" -O /tmp/terraform.zip \
    && unzip -o /tmp/terraform.zip -d /usr/local/bin/ \
    && rm /tmp/terraform.zip \
    && chmod +x /usr/local/bin/terraform

# GitHub CLI — used by gh_cli_execute tool in single-node GitHub subagent
RUN ARCH=$(uname -m) && \
    if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then ARCH="arm64"; else ARCH="amd64"; fi && \
    curl -sfL --retry 5 --retry-delay 3 \
       "https://github.com/cli/cli/releases/download/v2.90.0/gh_2.90.0_linux_${ARCH}.tar.gz" \
       -o /tmp/gh.tar.gz \
    && tar -xzf /tmp/gh.tar.gz -C /tmp \
    && mv /tmp/gh_2.90.0_linux_${ARCH}/bin/gh /usr/local/bin/gh \
    && chmod +x /usr/local/bin/gh \
    && rm -rf /tmp/gh.tar.gz /tmp/gh_*

# Go toolchain — needed at runtime by github-mcp-server (go run via STDIO)
COPY --from=golang /usr/local/go /usr/local/go

# Create appuser in final image
RUN groupadd -r appuser && useradd -r -g appuser -u 1001 -m appuser

WORKDIR /app

# Set env vars for uv & PATH
# PYTHONPATH lists every agent directory that contains an agent_<name>/ package so that
# imports like 'from agent_github.tools import ...' work in single-node mode.
# Only include dirs with agent_* packages; pure MCP-server dirs (e.g. agents/litellm/)
# must be omitted to avoid shadowing PyPI packages with same-named subdirectories.
ENV UV_PROJECT_ENVIRONMENT=/app/.venv \
    GOPATH="/home/appuser/go" \
    PATH="/app/.venv/bin:/usr/local/go/bin:/home/appuser/go/bin:${PATH}" \
    PYTHONPATH="/app/ai_platform_engineering/agents/github:/app/ai_platform_engineering/agents/backstage:/app/ai_platform_engineering/agents/jira:/app/ai_platform_engineering/agents/webex:/app/ai_platform_engineering/agents/argocd:/app/ai_platform_engineering/agents/aigateway:/app/ai_platform_engineering/agents/pagerduty:/app/ai_platform_engineering/agents/slack:/app/ai_platform_engineering/agents/splunk:/app/ai_platform_engineering/agents/komodor:/app/ai_platform_engineering/agents/confluence:/app/ai_platform_engineering/agents/aws:/app/ai_platform_engineering/agents/gitlab:/app/ai_platform_engineering/agents/netutils:/app/ai_platform_engineering/agents/victorops:/app/ai_platform_engineering/agents/weather:${PYTHONPATH}" \
    PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1

# Copy venv & code from builder
COPY --from=builder --chown=appuser:appuser /app /app

USER appuser

EXPOSE 8000

ENTRYPOINT [ "python", "-m", "ai_platform_engineering.multi_agents" ]
