# Steam Headless (Arch Linux)
# (WIP) An Arch variant of the steam-headless image
# It is curerently my intent to switch to arch as the main 
#   image base once SteamOS 3 is released (pending review)
#
FROM archlinux:latest
LABEL maintainer="Josh.5 <jsunnex@gmail.com>"

# Update package repos
RUN \
    echo "**** Update package manager ****" \
        && sed -i 's/^NoProgressBar/#NoProgressBar/g' /etc/pacman.conf \
        && echo -e "[multilib]\nInclude = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf \
    && \
    echo

# Update locale
RUN \
    echo "**** Configure locals ****" \
        && echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen \
        && locale-gen \
    && \
    echo
ENV \
    LANG=en_US.UTF-8 \
    LANGUAGE=en_US:en \
    LC_ALL=en_US.UTF-8

# Re-install certificates
RUN \
    echo "**** Install certificates ****" \
	    && pacman -Syu --noconfirm --needed \
            ca-certificates \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
    && \
    echo

# Install core packages
RUN \
    echo "**** Install tools ****" \
	    && pacman -Syu --noconfirm --needed \
            base-devel \
            bash \
            bash-completion \
            curl \
            docbook-xml \
            docbook-xsl \
            fakeroot \
            git \
            jq \
            less \
            locate \
            man-db \
            nano \
            net-tools \
            pciutils \
            pkg-config \
            procps \
            psmisc \
            psutils \
            rsync \
            screen \
            sudo \
            unzip \
            vim \
            wget \
            xz \
    && \
    echo "**** Install python ****" \
	    && pacman -Syu --noconfirm --needed \
            python \
            python-numpy \
            python-pip \
            python-setuptools \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
    && \
    echo

# Configure default user and set user env
ENV \
    PUID=99 \
    PGID=100 \
    UMASK=000 \
    USER="default" \
    USER_PASSWORD="password" \
    USER_HOME="/home/default" \
    TZ="Pacific/Auckland" \
    USER_LOCALES="en_US.UTF-8 UTF-8"
RUN \
    echo "**** Configure default user '${USER}' ****" \
        && mkdir -p \
            ${USER_HOME} \
        && useradd -d ${USER_HOME} -s /bin/bash ${USER} \
        && chown -R ${USER} \
            ${USER_HOME} \
        && echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
    && \
    echo

# Install yay
RUN \
    echo "**** Install Yay ****" \
	    && pacman -Sy \
	    && su - default -c 'git clone https://aur.archlinux.org/yay.git /tmp/yay && cd /tmp/yay && makepkg --noconfirm --syncdeps --install' \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
        && rm -rf \
            /tmp/yay* \
    && \
    echo

# Install supervisor
RUN \
    echo "**** Install supervisor ****" \
	    && pacman -Syu --noconfirm --needed \
            supervisor \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
    && \
    echo

# XFS requirements
RUN \
    echo "**** Install XFS requirements ****" \
	    && pacman -Syu --noconfirm --needed \
            xfsdump \
            xfsprogs \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
    && \
    echo

# Install mesa requirements
RUN \
    echo "**** Install mesa and vulkan requirements ****" \
	    && pacman -Syu --noconfirm --needed \
            glu \
            libva-mesa-driver \
            mesa-utils \
            mesa-vdpau \
            pciutils \
            vulkan-mesa-layers \
            vdpauinfo \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
    && \
    echo

# Install X Server requirements
ENV \
    XORG_SOCKET_DIR="/tmp/.X11-unix" \
    XDG_RUNTIME_DIR="/tmp/.X11-unix/run"
RUN \
    echo "**** Install X Server requirements ****" \
	    && pacman -Syu --noconfirm --needed \
            avahi \
            dbus \
            lib32-fontconfig \
            ttf-liberation \
            x11vnc \
            xorg \
            xorg-apps \
            xorg-font-util \
            xorg-fonts-misc \
            xorg-fonts-type1 \
            xorg-server \
            xorg-server-xephyr \
            xorg-server-xvfb \
            xorg-xauth \
            xorg-xbacklight \
            xorg-xhost \
            xorg-xinit \
            xorg-xinput \
            xorg-xkill \
            xorg-xprop \
            xorg-xrandr \
            xorg-xsetroot \
            xorg-xwininfo \
            xterm \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
    && \
    echo

# Install audio requirements
ENV \
    PULSE_SOCKET_DIR="/tmp/pulse" \
    PULSE_SERVER="unix:/tmp/pulse/pulse-socket"
RUN \
    echo "**** Install X Server requirements ****" \
	    && pacman -Syu --noconfirm --needed \
            alsa-utils \
            pavucontrol \
            pulseaudio \
            pulseaudio-alsa \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
    && \
    echo

# Install desktop environment
# TODO: Install equivelent of 'msttcorefonts' and 'fonts-vlgothic'
RUN \
    echo "**** Install desktop environment ****" \
	    && pacman -Syu --noconfirm --needed \
            gedit \
            xfce4 \
            xfce4-goodies \
            xfce4-terminal \
            ttf-liberation \
        # Delete these as they are not needed at all
        && rm -f \
            /usr/share/applications/software-properties-drivers.desktop \
            /usr/share/applications/xfce4-about.desktop \
            /usr/share/applications/xfce4-session-logout.desktop \
        # Hide these apps. They can be displayed if a user really wants them.
        && sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xfce4-accessibility-settings.desktop \
        && sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xfce4-color-settings.desktop \
        && sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xfce4-mail-reader.desktop \
        && sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/vim.desktop \
        && sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/thunar-settings.desktop \
        && sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/thunar.desktop \
        && sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/pavucontrol.desktop \
        && sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/x11vnc.desktop \
        && sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/xterm.desktop \
        && sed -i '/[Desktop Entry]/a\NoDisplay=true' /usr/share/applications/uxterm.desktop \
        # Force these apps to be "System" Apps rather than "Categories=System;Utility;Core;GTK;Filesystem;"
        && sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/xfce4-appfinder.desktop \
        && sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/thunar-bulk-rename.desktop \
        && sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/org.gnome.gedit.desktop \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
    && \
    echo

# TODO: Add support for flatpaks
# Note: Debian Bullseye had bubblewrap v0.4.1 which worked fine in the Nvidia docker runtime
#   At the moment this is only working beacuse /proc is being mounted again in 10-setup_user.sh
#   Need to find a better solution for this...
ARG BUBBLEWRAP_VERSION=0.8.0
ENV \
    XDG_DATA_DIRS="/home/default/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/"
RUN \
    echo "**** Install flatpak support ****" \
	    && pacman -Syu --noconfirm --needed \
            flatpak \
            gnome-software \
            xdg-desktop-portal-gtk \
    && \
    #echo "**** Build and install custom bubblewrap ****" \
    #    && cd /tmp \
    #    && wget -O /tmp/bubblewrap-${BUBBLEWRAP_VERSION:?}.tar.xz https://github.com/containers/bubblewrap/releases/download/v${BUBBLEWRAP_VERSION:?}/bubblewrap-${BUBBLEWRAP_VERSION:?}.tar.xz \
    #    && tar -xvf /tmp/bubblewrap-${BUBBLEWRAP_VERSION:?}.tar.xz \
    #    && cd /tmp/bubblewrap-${BUBBLEWRAP_VERSION:?} \
    #    && sed -i 's|die ("Unexpected capabilities but not setuid, old file caps config?");|printf ("Unexpected capabilities but not setuid, old file caps config?");|' ./bubblewrap.c \
    #    && ./autogen.sh \
    #    && make clean \
    #    && make \
    #    && make install
    #&& \
    echo "**** Configure flatpak ****" \
        && chmod u-s /usr/bin/bwrap \
        && flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
    && \
    echo

# Install noVNC
# TODO: Add nginx or remove the whole proxy setup and just connect directly for audio (I think that is the better option)
ARG NOVNC_VERSION=1.2.0
RUN \
    echo "**** Fetch noVNC ****" \
        && cd /tmp \
        && wget -O /tmp/novnc.tar.gz https://github.com/novnc/noVNC/archive/v${NOVNC_VERSION}.tar.gz \
    && \
    echo "**** Extract noVNC ****" \
        && cd /tmp \
        && tar -xvf /tmp/novnc.tar.gz \
    && \
    echo "**** Configure noVNC ****" \
        && cd /tmp/noVNC-${NOVNC_VERSION} \
        && sed -i 's/credentials: { password: password } });/credentials: { password: password },\n                           wsProtocols: ["'"binary"'"] });/g' app/ui.js \
        && mkdir -p /opt \
        && rm -rf /opt/noVNC \
        && cd /opt \
        && mv -f /tmp/noVNC-${NOVNC_VERSION} /opt/noVNC \
        && cd /opt/noVNC \
        && ln -s vnc.html index.html \
        && chmod -R 755 /opt/noVNC \
    && \
    echo "**** Modify noVNC title ****" \
        && sed -i '/    document.title =/c\    document.title = "Steam Headless - noVNC";' \
            /opt/noVNC/app/ui.js \
    && \
    echo "**** Install nginx support ****" \
	    && pacman -Syu --noconfirm --needed \
            nginx \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
        && rm -rf \
            /tmp/noVNC* \
            /tmp/novnc.tar.gz \
    && \
    echo

# Install Websockify
ARG WEBSOCKETIFY_VERSION=0.10.0
RUN \
    echo "**** Fetch Websockify ****" \
        && cd /tmp \
        && wget -O /tmp/websockify.tar.gz https://github.com/novnc/websockify/archive/v${WEBSOCKETIFY_VERSION}.tar.gz \
    && \
    echo "**** Extract Websockify ****" \
        && cd /tmp \
        && tar -xvf /tmp/websockify.tar.gz \
    && \
    echo "**** Install Websockify to main ****" \
        && cd /tmp/websockify-${WEBSOCKETIFY_VERSION} \
        && python3 ./setup.py install \
    && \
    echo "**** Install Websockify to noVNC path ****" \
        && cd /tmp \
        && mv -v /tmp/websockify-${WEBSOCKETIFY_VERSION} /opt/noVNC/utils/websockify \
    && \
    echo "**** Section cleanup ****" \
        && rm -rf \
            /tmp/websockify-* \
            /tmp/websockify.tar.gz \
    && \
    echo

# Setup browser audio streaming deps
RUN \
    echo "**** Install audio streaming deps ****" \
        && pacman -Syu --noconfirm --needed \
            bzip2 \
            gst-libav \
            gst-plugins-bad \
            gst-plugins-base \
            gst-plugins-good \
            gst-plugins-ugly \
    && \
    echo "**** Fetch ucspi-tcp ****" \
        && mkdir -p /tmp/ucspi-tcp-0.88 \
        && cd /tmp \
        #&& wget -O /tmp/ucspi-tcp.tar.gz https://github.com/trafficgate/ucspi-tcp/archive/refs/heads/master.tar.gz \
        && wget -O /tmp/ucspi-tcp.tar.gz http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz \
        && cd /tmp/ucspi-tcp-0.88 \
        && tar -xvf /tmp/ucspi-tcp.tar.gz --strip-components=1 \
    && \
    echo "**** Build and install ucspi-tcp ****" \
        && wget -O /tmp/ucspi-tcp-0.88/ucspi-tcp-0.88.errno.patch https://git.alpinelinux.org/aports/plain/testing/ucspi-tcp/ucspi-tcp-0.88.errno.patch \
        && wget -O /tmp/ucspi-tcp-0.88/ucspi-tcp-0.88.a_record.patch https://git.alpinelinux.org/aports/plain/testing/ucspi-tcp/ucspi-tcp-0.88.a_record.patch \
        && patch -p1 --input=ucspi-tcp-0.88.errno.patch \
        && patch -p1 --input=ucspi-tcp-0.88.a_record.patch \
        && sed -i 's|^/usr/local|/usr|' /tmp/ucspi-tcp-0.88/conf-home \
        && make \
	    && for f in tcpserver tcprules tcprulescheck argv0 recordio tcpclient *\@ tcpcat mconnect mconnect-io addcr delcr fixcrio rblsmtpd; do \
            cp $f /usr/bin/$f; \
        done \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
        && rm -rf \
            /tmp/ucspi-tcp-* \
    && \
    echo

# Install Steam
RUN \
    echo "**** Install X Server requirements ****" \
	    && pacman -Syu --noconfirm --needed \
            steam \
    && \
    echo "**** Section cleanup ****" \
	    && pacman -Scc --noconfirm \
        && rm -fr /var/lib/pacman/sync/* \
    && \
    echo

# Add FS overlay
COPY overlay /

RUN \
    echo "**** Setup Steam Supervisor ****" \
            && sed -i 's#/usr/games/steam#/usr/bin/steam#g' /etc/supervisor.d/steam.ini \
    && \
    echo

# Set display environment variables
ENV \
    DISPLAY_CDEPTH="24" \
    DISPLAY_REFRESH="120" \
    DISPLAY_SIZEH="900" \
    DISPLAY_SIZEW="1600" \
    DISPLAY_VIDEO_PORT="DFP" \
    DISPLAY=":55"
ENV \
    NVIDIA_DRIVER_CAPABILITIES="all" \
    NVIDIA_VISIBLE_DEVICES="all"

# Set container configuration environment variables
ENV \
    MODE="primary" \
    WEB_UI_MODE="vnc" \
    ENABLE_VNC_AUDIO="true" \
    NEKO_PASSWORD=neko \
    NEKO_PASSWORD_ADMIN=admin \
    ENABLE_STEAM="true" \
    STEAM_ARGS="-silent" \
    ENABLE_SUNSHINE="false" \
    ENABLE_EVDEV_INPUTS="false"

# Configure required ports
ENV \
    PORT_NOVNC_WEB="8083" \
    NEKO_NAT1TO1=""

# Expose the required ports
EXPOSE 8083

# Set entrypoint
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
