# Web build stage — compile SPA from source
# node:22-alpine, 2026-03-09
FROM node@sha256:8094c002d08262dba12645a3b4a15cd6cd627d30bc782f53229a2ec13ee22a00 AS web-builder
WORKDIR /web
COPY web/package.json web/package-lock.json ./
RUN npm ci
COPY web/src/ src/
COPY web/build.sh build.sh
RUN sh build.sh

# Lint stage — fast feedback on formatting and lint issues
# golangci/golangci-lint:v2.1.6, 2026-03-02
FROM golangci/golangci-lint@sha256:568ee1c1c53493575fa9494e280e579ac9ca865787bafe4df3023ae59ecf299b AS lint
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Create placeholder files so //go:embed dist/* in web/embed.go resolves
# without depending on the web-builder stage (lint should fail fast)
RUN mkdir -p web/dist && touch web/dist/index.html web/dist/style.css web/dist/app.js
RUN make fmt-check
RUN make lint

# Build stage
# golang:1.24-alpine, 2026-02-26
FROM golang@sha256:8bee1901f1e530bfb4a7850aa7a479d17ae3a18beb6e09064ed54cfd245b7191 AS builder
WORKDIR /src
RUN apk add --no-cache git build-base make

# Force BuildKit to run the lint stage before proceeding
COPY --from=lint /src/go.sum /dev/null

COPY go.mod go.sum ./
RUN go mod download

COPY . .
COPY --from=web-builder /web/dist/ web/dist/

RUN make test

# Build static binaries (no cgo needed at runtime — modernc.org/sqlite is pure Go)
ARG VERSION=dev
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w -X main.Version=${VERSION}" -o /neoircd ./cmd/neoircd/
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /neoirc-cli ./cmd/neoirc-cli/

# Runtime stage
# alpine:3.21, 2026-02-26
FROM alpine@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709
RUN apk add --no-cache ca-certificates \
    && addgroup -S neoirc && adduser -S neoirc -G neoirc \
    && mkdir -p /var/lib/neoirc \
    && chown neoirc:neoirc /var/lib/neoirc
COPY --from=builder /neoircd /usr/local/bin/neoircd

USER neoirc
EXPOSE 8080 6667
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD wget -qO- http://localhost:8080/.well-known/healthcheck.json || exit 1
ENTRYPOINT ["neoircd"]
