#!/bin/bash
set -u
export LANG=C.UTF-8
step() { echo "== STEP $*"; }
fail() { echo "== FAIL $*"; exit 1; }
[ "$(id -u)" = 0 ] || fail "needs root: install Flatpak from the launcher's Store, which runs this as root"

if command -v pacman >/dev/null 2>&1; then
PACKAGES="flatpak ostree appstream libxmlb libmalcontent libfyaml accountsservice composefs xdg-dbus-proxy"
while read -r pkg probe; do
  [ -n "$pkg" ] || continue
  compgen -G "$probe" >/dev/null || PACKAGES="$PACKAGES $pkg"
done <<'NEEDS'
json-glib /usr/lib/libjson-glib-1.0.so.0
fuse3 /usr/lib/libfuse3.so.4
fuse-common /etc/fuse.conf
libsodium /usr/lib/libsodium.so.*
libstemmer /usr/lib/libstemmer.so.*
polkit /usr/lib/libpolkit-gobject-1.so.0
mpdecimal /usr/lib/libmpdec.so.*
python /usr/bin/python3
libgirepository /usr/lib/libgirepository-2.0.so.0
gobject-introspection-runtime /usr/lib/girepository-1.0/GObject-2.0.typelib
python-gobject /usr/lib/python3*/site-packages/gi/__init__.py
NEEDS
WORK=/var/cache/droiddeck-flatpak
CONF=$WORK/pacman.conf
mkdir -p "$WORK/pkg" "$WORK/db" || fail "cannot create $WORK"
exec 9>"$WORK/setup.lock" && flock -n 9 || fail "another Flatpak setup is still running"

OVERSEAS="https://ca.us.mirror.archlinuxarm.org https://fl.us.mirror.archlinuxarm.org https://de3.mirror.archlinuxarm.org https://nl.mirror.archlinuxarm.org"
MAINLAND=""
for m in https://mirrors.tuna.tsinghua.edu.cn/archlinuxarm https://mirrors.ustc.edu.cn/archlinuxarm \
         https://mirrors.bfsu.edu.cn/archlinuxarm https://mirrors.sjtug.sjtu.edu.cn/archlinuxarm; do
  if curl -fsS -r 0-0 --connect-timeout 4 --max-time 8 -o /dev/null "$m/aarch64/core/core.db" 2>/dev/null; then
    MAINLAND="$MAINLAND $m"
  fi
done
{ for m in $MAINLAND $OVERSEAS; do
    echo "Server = $m/\$arch/\$repo"; done
  grep '^Server' /etc/pacman.d/mirrorlist 2>/dev/null; } > "$WORK/mirrorlist"
sed -e 's/^DownloadUser/#DownloadUser/' \
    -e 's/^\[options\]/[options]\nDisableSandbox/' \
    -e "s#^Include *= */etc/pacman.d/mirrorlist#Include = $WORK/mirrorlist#" \
    /etc/pacman.conf > "$CONF" || fail "no /etc/pacman.conf"

if [ ! -f /etc/pacman.d/gnupg/pubring.gpg ] && [ ! -f /etc/pacman.d/gnupg/pubring.kbx ]; then
  step "Preparing the package keyring"
  pacman-key --init >/dev/null 2>&1 || fail "pacman-key --init failed"
  pacman-key --populate archlinuxarm >/dev/null 2>&1 || fail "pacman-key --populate failed"
fi

step "Reading the package lists"
rm -f "$WORK/db/db.lck"
sync_log=$(pacman --config "$CONF" --dbpath "$WORK/db" --noconfirm -Sy 2>&1) \
  || sync_log=$(pacman --config "$CONF" --dbpath "$WORK/db" --noconfirm -Sy 2>&1)
if [ ! -f "$WORK/db/sync/extra.db" ]; then
  printf '%s\n' "$sync_log" | tail -3
  reason=$(printf '%s\n' "$sync_log" | grep -m1 -i '^error' | cut -c1-160)
  fail "could not reach the Arch Linux ARM mirrors${reason:+ ($reason)}"
fi

step "Downloading Flatpak"
out=$(pacman --config "$CONF" --dbpath "$WORK/db" --cachedir "$WORK/pkg" --noconfirm -Sw -dd $PACKAGES 2>&1)
rc=$?
echo "$out" | grep -vE '^\s*$' | tail -4
[ $rc -eq 0 ] || fail "download failed"

step "Installing Flatpak"
for name in $PACKAGES; do
  ver=$(pacman --config "$CONF" --dbpath "$WORK/db" -Sp --print-format '%v' -dd "$name" 2>/dev/null | tail -1)
  file=$(ls "$WORK/pkg/$name-$ver-"*.pkg.tar.* 2>/dev/null | grep -v '\.sig$' | head -1)
  [ -n "$file" ] || fail "no package file for $name $ver"
  bsdtar -xpf "$file" -C / --exclude .PKGINFO --exclude .BUILDINFO --exclude .MTREE --exclude .INSTALL \
    || fail "could not unpack $name"
  echo "$name $ver" >> "$WORK/installed.new"
done
mv -f "$WORK/installed.new" "$WORK/installed"
find "$WORK/pkg" -type f -mtime +1 -delete 2>/dev/null

else
  command -v flatpak >/dev/null 2>&1 || fail "Flatpak is missing from the runtime"
  WORK=$(mktemp -d)
  trap 'rm -rf "$WORK"' EXIT
fi
missing=$(for f in /usr/bin/flatpak /usr/lib/libflatpak.so.0 /usr/lib/libostree-1.so.1 /usr/lib/aarch64-linux-gnu/libflatpak.so.0 /usr/lib/aarch64-linux-gnu/libostree-1.so.1 /usr/bin/xdg-dbus-proxy; do
  [ -e "$f" ] || continue
  ldd "$f" 2>&1 | grep -E 'not found|version .* not found'
done | sort -u)
[ -z "$missing" ] || { echo "$missing"; fail "Flatpak is missing libraries"; }
flatpak --version >/dev/null 2>&1 || fail "flatpak does not start"
python3 -c 'import gi; gi.require_version("Flatpak", "1.0"); from gi.repository import Flatpak' 2>/dev/null \
  || fail "the store helper cannot load libflatpak from Python"

step "Adding Flathub"
export FLATPAK_BWRAP=/usr/local/bin/droiddeck-bwrap
cat > "$WORK/flathub.flatpakrepo" <<'REPO'
[Flatpak Repo]
Title=Flathub
Url=https://dl.flathub.org/repo/
Homepage=https://flathub.org/
Comment=Central repository of Flatpak applications
Description=Central repository of Flatpak applications
Icon=https://dl.flathub.org/repo/logo.svg
GPGKey=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
REPO
if ! flatpak remote-list --columns=name 2>/dev/null | grep -qx flathub; then
  out=$(flatpak remote-add --user --if-not-exists flathub "$WORK/flathub.flatpakrepo" 2>&1)
  rc=$?
  echo "$out"
  [ $rc -eq 0 ] || fail "could not add the Flathub remote: $(echo "$out" | grep -v '^[[:space:]]*$' | tail -1)"
fi
echo "== DONE $(flatpak --version)"
