# =============================================================================
# PostgreSQL 18 + PostGIS 3.6 for CloudNativePG (ARM64 build from source)
# =============================================================================
# This Dockerfile builds PostGIS from source for ARM64 architecture since
# the official postgis/postgis images don't have ARM64 support for PG18 yet.
#
# Build: docker build --platform linux/arm64 -t cnpg-postgis:18-3.6 .
# Test:  docker run --rm -e POSTGRES_PASSWORD=test cnpg-postgis:18-3.6 postgres --version
# =============================================================================

# -----------------------------------------------------------------------------
# Build arguments - Pin versions for reproducible builds
# -----------------------------------------------------------------------------
ARG PG_MAJOR=18
ARG POSTGIS_VERSION=3.6.1
ARG GEOS_VERSION=3.13.0
# PROJ 9.4.1 is more stable for building; 9.5.x has additional deps
ARG PROJ_VERSION=9.4.1
ARG GDAL_VERSION=3.10.1
ARG SFCGAL_VERSION=2.0.0

# =============================================================================
# Stage 1: Build PostGIS and dependencies from source
# =============================================================================
FROM postgres:${PG_MAJOR}-bookworm AS builder

ARG PG_MAJOR
ARG POSTGIS_VERSION
ARG GEOS_VERSION
ARG PROJ_VERSION
ARG GDAL_VERSION

# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    # Build tools
    build-essential \
    cmake \
    ninja-build \
    pkg-config \
    git \
    wget \
    ca-certificates \
    # PostgreSQL development
    postgresql-server-dev-${PG_MAJOR} \
    # Required libraries
    libxml2-dev \
    libjson-c-dev \
    libprotobuf-c-dev \
    protobuf-c-compiler \
    libsqlite3-dev \
    sqlite3 \
    libtiff-dev \
    libcurl4-openssl-dev \
    libssl-dev \
    zlib1g-dev \
    liblzma-dev \
    libzstd-dev \
    libpng-dev \
    libjpeg-dev \
    libwebp-dev \
    # Additional dependencies
    libpcre2-dev \
    autoconf \
    automake \
    libtool \
    # PROJ additional requirements
    nlohmann-json3-dev \
    libgeotiff-dev \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /build

# -----------------------------------------------------------------------------
# Build GEOS (Geometry Engine)
# -----------------------------------------------------------------------------
RUN wget -q https://download.osgeo.org/geos/geos-${GEOS_VERSION}.tar.bz2 \
    && tar xjf geos-${GEOS_VERSION}.tar.bz2 \
    && cd geos-${GEOS_VERSION} \
    && mkdir build && cd build \
    && cmake .. \
        -G Ninja \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=/usr/local \
        -DBUILD_TESTING=OFF \
    && ninja \
    && ninja install \
    && cd /build && rm -rf geos-*

# -----------------------------------------------------------------------------
# Build PROJ (Cartographic Projections)
# -----------------------------------------------------------------------------
RUN wget -q https://download.osgeo.org/proj/proj-${PROJ_VERSION}.tar.gz \
    && tar xzf proj-${PROJ_VERSION}.tar.gz \
    && cd proj-${PROJ_VERSION} \
    && mkdir build && cd build \
    && cmake .. \
        -G Ninja \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=/usr/local \
        -DBUILD_TESTING=OFF \
        -DENABLE_CURL=ON \
        -DENABLE_TIFF=ON \
    && ninja \
    && ninja install \
    && cd /build && rm -rf proj-*

# Update library cache after PROJ install
RUN ldconfig

# -----------------------------------------------------------------------------
# Build GDAL (Geospatial Data Abstraction Library)
# -----------------------------------------------------------------------------
RUN wget -q https://github.com/OSGeo/gdal/releases/download/v${GDAL_VERSION}/gdal-${GDAL_VERSION}.tar.gz \
    && tar xzf gdal-${GDAL_VERSION}.tar.gz \
    && cd gdal-${GDAL_VERSION} \
    && mkdir build && cd build \
    && cmake .. \
        -G Ninja \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=/usr/local \
        -DBUILD_TESTING=OFF \
        -DBUILD_APPS=OFF \
        -DGDAL_BUILD_OPTIONAL_DRIVERS=OFF \
        -DOGR_BUILD_OPTIONAL_DRIVERS=OFF \
        -DGDAL_USE_GEOS=ON \
        -DGDAL_USE_PROJ=ON \
        -DGDAL_USE_TIFF=ON \
        -DGDAL_USE_GEOTIFF=ON \
        -DGDAL_USE_PNG=ON \
        -DGDAL_USE_JPEG=ON \
        -DGDAL_USE_WEBP=ON \
        -DGDAL_USE_CURL=ON \
        -DGDAL_USE_SQLITE3=ON \
        -DGDAL_USE_POSTGRESQL=ON \
    && ninja \
    && ninja install \
    && cd /build && rm -rf gdal-*

# Update library cache after GDAL install
RUN ldconfig

# -----------------------------------------------------------------------------
# Build PostGIS
# -----------------------------------------------------------------------------
# Set library paths so configure can find GDAL, GEOS, PROJ
ENV LD_LIBRARY_PATH=/usr/local/lib
ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

RUN wget -q https://download.osgeo.org/postgis/source/postgis-${POSTGIS_VERSION}.tar.gz \
    && tar xzf postgis-${POSTGIS_VERSION}.tar.gz \
    && cd postgis-${POSTGIS_VERSION} \
    && LDFLAGS="-L/usr/local/lib" \
       CPPFLAGS="-I/usr/local/include" \
       ./configure \
        --with-pgconfig=/usr/lib/postgresql/${PG_MAJOR}/bin/pg_config \
        --with-geosconfig=/usr/local/bin/geos-config \
        --with-projdir=/usr/local \
        --with-gdalconfig=/usr/local/bin/gdal-config \
        --with-protobufdir=/usr \
        --without-sfcgal \
    && make -j$(nproc) \
    && make install DESTDIR=/postgis-install \
    && cd /build && rm -rf postgis-*

# =============================================================================
# Stage 2: Get CNPG tools (barman-cloud for backup/restore)
# =============================================================================
FROM ghcr.io/cloudnative-pg/postgresql:${PG_MAJOR} AS cnpg-tools

# =============================================================================
# Stage 3: Final runtime image
# =============================================================================
FROM postgres:${PG_MAJOR}-bookworm

ARG PG_MAJOR
ARG POSTGIS_VERSION

LABEL maintainer="Keyboard Vagabond <admin@mail.keyboardvagabond.com>"
LABEL description="PostgreSQL ${PG_MAJOR} with PostGIS ${POSTGIS_VERSION} for CloudNativePG (ARM64)"
LABEL org.opencontainers.image.source="https://keyboardvagabond.com"

ENV POSTGIS_MAJOR=3
ENV POSTGIS_VERSION=${POSTGIS_VERSION}

# Install runtime dependencies only (no build tools)
RUN apt-get update && apt-get install -y --no-install-recommends \
    # Runtime libraries for GEOS/PROJ/GDAL/PostGIS
    libxml2 \
    libjson-c5 \
    libprotobuf-c1 \
    libsqlite3-0 \
    libtiff6 \
    libcurl4 \
    libssl3 \
    zlib1g \
    liblzma5 \
    libzstd1 \
    libpng16-16 \
    libjpeg62-turbo \
    libwebp7 \
    libpcre2-8-0 \
    # Additional utilities
    ca-certificates \
    curl \
    jq \
    # Python for barman-cloud
    python3 \
    python3-boto3 \
    python3-botocore \
    && rm -rf /var/lib/apt/lists/*

# Copy compiled libraries from builder
COPY --from=builder /usr/local/lib/ /usr/local/lib/
COPY --from=builder /usr/local/share/proj/ /usr/local/share/proj/
COPY --from=builder /usr/local/share/gdal/ /usr/local/share/gdal/
COPY --from=builder /usr/local/bin/geos-config /usr/local/bin/
COPY --from=builder /usr/local/bin/gdal-config /usr/local/bin/
COPY --from=builder /usr/local/bin/proj /usr/local/bin/
COPY --from=builder /usr/local/bin/projinfo /usr/local/bin/

# Copy PostGIS installation (modern PostGIS uses extension dir, not contrib)
COPY --from=builder /postgis-install/usr/lib/postgresql/${PG_MAJOR}/lib/ /usr/lib/postgresql/${PG_MAJOR}/lib/
COPY --from=builder /postgis-install/usr/share/postgresql/${PG_MAJOR}/extension/ /usr/share/postgresql/${PG_MAJOR}/extension/

# Update library cache
RUN ldconfig

# Copy barman-cloud tools from CNPG image (they're in /usr/local/bin/)
COPY --from=cnpg-tools /usr/local/bin/barman* /usr/local/bin/

# -----------------------------------------------------------------------------
# Fix user ID for CloudNativePG compatibility (requires UID 26)
# -----------------------------------------------------------------------------
RUN set -eux; \
    CURRENT_UID=$(id -u postgres); \
    if [ "$CURRENT_UID" != "26" ]; then \
        # Check if UID 26 is already in use
        if getent passwd 26 >/dev/null 2>&1; then \
            EXISTING_USER=$(getent passwd 26 | cut -d: -f1); \
            usermod -u 9999 "$EXISTING_USER" 2>/dev/null || true; \
        fi; \
        # Change postgres user to UID 26
        usermod -u 26 postgres; \
        # Fix ownership of postgres directories
        find /var/lib/postgresql -user $CURRENT_UID -exec chown -h 26 {} \; 2>/dev/null || true; \
        find /var/run/postgresql -user $CURRENT_UID -exec chown -h 26 {} \; 2>/dev/null || true; \
        chown -R postgres:postgres /var/lib/postgresql /var/run/postgresql 2>/dev/null || true; \
    fi

# Copy initialization and update scripts
RUN mkdir -p /docker-entrypoint-initdb.d
COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/10_postgis.sh
COPY ./update-postgis.sh /usr/local/bin/
RUN chmod +x /docker-entrypoint-initdb.d/10_postgis.sh /usr/local/bin/update-postgis.sh

# -----------------------------------------------------------------------------
# Verify installation
# -----------------------------------------------------------------------------
RUN set -eux; \
    postgres --version; \
    echo "GEOS: $(geos-config --version)"; \
    echo "PROJ: $(projinfo 2>&1 | head -1 || echo 'installed')"; \
    echo "GDAL: $(gdal-config --version)"; \
    id postgres; \
    ls -la /usr/lib/postgresql/${PG_MAJOR}/lib/postgis*.so || true

# Switch to postgres user
USER postgres

EXPOSE 5432
