# Build args sourced from packaging/linux/versions.env via build.sh.
# Defining ARGs without defaults makes the build fail loud if any pin
# is missing — caller must source versions.env.
ARG UBUNTU_BASE

FROM ubuntu:${UBUNTU_BASE}

ARG WX_VERSION
ARG WX_GIT_URL
ARG WX_COMMIT
ARG LINUXDEPLOY_VERSION
ARG LINUXDEPLOY_GTK_SHA
ARG LIBUPNP_VERSION
ARG LIBUPNP_TARBALL_URL
ARG LIBUPNP_SHA256
ARG APPINDICATOR_VERSION
ARG APPINDICATOR_TARBALL_URL
ARG APPINDICATOR_SHA256

ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Etc/UTC

RUN apt-get update && apt-get install -y --no-install-recommends \
        build-essential \
        ccache \
        cmake \
        ninja-build \
        pkg-config \
        git \
        ca-certificates \
        wget \
        file \
        fuse \
        # aMule build deps (matches CI Ubuntu job).
        # wxWidgets is built from source below — Ubuntu 22.04 doesn't
        # package wx 3.2.x, and bumping the base to 24.04 would push
        # the glibc floor to 2.39 and drop Ubuntu 22.04 LTS users.
        binutils-dev \
        gettext \
        libboost-dev \
        libcrypto++-dev \
        libgd-dev \
        libgeoip-dev \
        # libmaxminddb: enables IP2Country (country flag lookup) when
        # the user supplies their own GeoLite2-Country.mmdb at runtime.
        # We don't ship the database — MaxMind's licence forbids
        # redistribution; users drop it in ~/.aMule/.
        libmaxminddb-dev \
        libreadline-dev \
        # libupnp-dev intentionally omitted: Ubuntu 22.04 only ships the
        # ancient 1.8.x line. The pinned 22.x is built from source below.
        # libcurl: backend for wxWebRequest, which aMule's HTTP path requires.
        libcurl4-openssl-dev \
        # GTK3 dev headers (linker target for wx) + Wayland/X11 client headers
        libgtk-3-dev \
        libwayland-dev \
        # Build deps for libayatana-appindicator, which is built from source
        # below rather than taken from the archive -- see the RUN block for
        # why. The library itself enables the StatusNotifierItem (SNI)
        # tray-icon backend in MuleTrayIcon; without it the tray falls
        # back to wxTaskBarIcon → legacy GtkStatusIcon, which GNOME
        # dropped in 3.26 and wlroots compositors never implemented.
        # Ubuntu's GNOME Shell extension renders both, but Fedora /
        # vanilla GNOME / Sway need the SNI path to see the icon at all.
        libayatana-indicator3-dev \
        libdbusmenu-gtk3-dev \
        # g-ir-scanner. appindicator calls find_package(GObjectIntrospection
        # REQUIRED) but the find module does not fail configure when the
        # scanner is missing -- it leaves INTROSPECTION_SCANNER empty and the
        # .gir rule then runs its own first argument as the command, failing
        # with "app-indicator.c: not found" at build time instead.
        libgirepository1.0-dev \
        # AppImage runtime / linuxdeploy-plugin-gtk deps
        libglib2.0-bin \
        libgdk-pixbuf-2.0-0 \
        librsvg2-common \
        gtk-update-icon-cache \
        desktop-file-utils \
        # zsync delta-update tool used by appimagetool
        zsync \
        # unsquashfs to extract AppImage type-2 contents directly,
        # bypassing the AppImage runtime which doesn't run under
        # QEMU user-mode emulation when cross-building.
        squashfs-tools \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# libupnp / pupnp from source: Ubuntu 22.04 only packages the ancient 1.8.x
# line, so build the pinned 22.x (shared, so linuxdeploy bundles the .so into
# the AppImage). pupnp 22.x is CMake-only. CMAKE_INSTALL_LIBDIR=lib keeps
# libupnp.pc / .so / the UPNP CMake config out of lib64 where pkg-config, cmake
# and ldconfig wouldn't find them.
# libayatana-appindicator from source: 22.04 ships 0.5.90, and only 0.6.0
# answers the StatusNotifierItem Activate D-Bus method, which is what a host
# sends on left-click. On anything older the tray icon can only open its menu,
# so left-click and right-click do the same thing (discussion #1115). Shared,
# so linuxdeploy bundles the .so into the AppImage. Its own dependencies
# (ayatana-indicator3 >= 0.8.4, dbusmenu-gtk3, GTK >= 3.24) are satisfied by
# the archive packages installed above, so nothing else needs building.
RUN wget -qO /tmp/appindicator.tar.gz "${APPINDICATOR_TARBALL_URL}" \
    && echo "${APPINDICATOR_SHA256}  /tmp/appindicator.tar.gz" | sha256sum -c - \
    && mkdir -p /tmp/appindicator && tar -xf /tmp/appindicator.tar.gz -C /tmp/appindicator --strip-components=1 \
    && cmake -S /tmp/appindicator -B /tmp/appindicator/build -G Ninja -DCMAKE_BUILD_TYPE=Release \
        -DFLAVOUR_GTK3=ON -DENABLE_BINDINGS_MONO=OFF -DENABLE_BINDINGS_VALA=OFF \
        -DENABLE_TESTS=OFF -DENABLE_GTKDOC=OFF \
        -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_INSTALL_LIBDIR=lib \
    && cmake --build /tmp/appindicator/build && cmake --install /tmp/appindicator/build \
    && ldconfig \
    && rm -rf /tmp/appindicator /tmp/appindicator.tar.gz

RUN wget -qO /tmp/libupnp.tar.gz "${LIBUPNP_TARBALL_URL}" \
    && echo "${LIBUPNP_SHA256}  /tmp/libupnp.tar.gz" | sha256sum -c - \
    && mkdir -p /tmp/libupnp && tar -xf /tmp/libupnp.tar.gz -C /tmp/libupnp --strip-components=1 \
    && cmake -S /tmp/libupnp -B /tmp/libupnp/build -G Ninja -DCMAKE_BUILD_TYPE=Release \
        -DUPNP_BUILD_SHARED=ON -DUPNP_BUILD_STATIC=OFF \
        -DUPNP_BUILD_SAMPLES=OFF -DUPNP_BUILD_TESTS=OFF -Dreuseaddr=ON -Dipv6=ON \
        -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_INSTALL_LIBDIR=lib \
    && cmake --build /tmp/libupnp/build && cmake --install /tmp/libupnp/build \
    && ldconfig \
    && rm -rf /tmp/libupnp /tmp/libupnp.tar.gz

# wxWidgets from source. --disable-shared so wx links statically into
# aMule, sidestepping the wxGTK-SONAME-mismatch problem AppImage users
# hit on distros shipping a different wx 3.2 patch level than the
# Ubuntu 22.04 base. Subsystems aMule doesn't use are disabled to
# shrink the static archives.
WORKDIR /opt/wxwidgets
# Fetched from the 3.2 branch at a pinned commit, not a release tarball: no
# 3.2.x release yet carries the wxEpollDispatcher unregister fix amuled needs
# (amule-org/amule#1136). Fetching the SHA directly keeps this reproducible
# and avoids cloning the full history; submodules supply wx's bundled
# third-party sources. Revert to the tarball when 3.2.12 ships.
RUN git init wx \
    && cd wx \
    && git remote add origin "${WX_GIT_URL}" \
    && git fetch --depth 1 origin "${WX_COMMIT}" \
    && git checkout FETCH_HEAD \
    && git submodule update --init --depth 1 --recursive \
    && ./configure \
        --prefix=/usr/local \
        --with-gtk=3 \
        --enable-unicode \
        --disable-debug \
        --disable-shared \
        --disable-mediactrl \
        --disable-webview \
        --disable-richtext \
        --disable-aui \
        --disable-html \
        --without-libtiff \
        --without-libjbig \
        --without-libmspack \
        --without-opengl \
        --with-libcurl \
    && make -j"$(nproc)" \
    && make install \
    && cd / \
    && rm -rf /opt/wxwidgets

# linuxdeploy is fetched from a tagged Release (alpha tags get pruned;
# bump LINUXDEPLOY_VERSION when an old pin 404s).
# linuxdeploy-plugin-gtk has no Releases — fetched from a pinned commit
# on master via raw.githubusercontent.com.
WORKDIR /opt/linuxdeploy
# Helper: find the squashfs offset in an AppImage and unsquashfs it.
# We can't use `./X.AppImage --appimage-extract` here because the
# AppImage runtime ELF doesn't execute under QEMU user-mode emulation
# (some FUSE-related syscalls are unsupported), and we need this to
# work both natively and when cross-building.
#
# AppImage type-2 = small ELF runtime + appended squashfs. The
# squashfs starts at some offset, marked by the 'hsqs' magic at its
# beginning. The ELF can also contain false 'hsqs' substrings, so
# iterate over candidates and take the first one whose superblock
# parses cleanly.
COPY <<'EOF' /usr/local/bin/extract-appimage
#!/bin/bash
set -euo pipefail
src="$1"; dst="$2"
for offset in $(grep -aob 'hsqs' "${src}" | cut -d: -f1); do
    if unsquashfs -q -o "${offset}" -d "${dst}" "${src}" >/dev/null 2>&1; then
        exit 0
    fi
done
echo "extract-appimage: no valid squashfs found in ${src}" >&2
exit 1
EOF
RUN chmod +x /usr/local/bin/extract-appimage \
    && ARCH=$(uname -m) \
    && wget -q "https://github.com/linuxdeploy/linuxdeploy/releases/download/${LINUXDEPLOY_VERSION}/linuxdeploy-${ARCH}.AppImage" -O linuxdeploy.AppImage \
    && wget -q "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/${LINUXDEPLOY_GTK_SHA}/linuxdeploy-plugin-gtk.sh" -O linuxdeploy-plugin-gtk.sh \
    && wget -q "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-${ARCH}.AppImage" -O appimagetool.AppImage \
    && chmod +x linuxdeploy-plugin-gtk.sh \
    && extract-appimage linuxdeploy.AppImage linuxdeploy-extracted \
    && extract-appimage appimagetool.AppImage appimagetool-extracted \
    && ln -s /opt/linuxdeploy/linuxdeploy-extracted/AppRun /usr/local/bin/linuxdeploy \
    && ln -s /opt/linuxdeploy/linuxdeploy-plugin-gtk.sh /usr/local/bin/linuxdeploy-plugin-gtk \
    && ln -s /opt/linuxdeploy/appimagetool-extracted/AppRun /usr/local/bin/appimagetool

WORKDIR /work
ENTRYPOINT ["/work/packaging/linux/appimage/build.sh"]
