#!/bin/sh
# Add the etawen-ps5 package repository to this system.
# https://repo.etawen.dev — kernel, wifi driver, fan/boost control, payload SDK.
#
# Usage: curl -fsSL https://repo.etawen.dev/install.sh | sh
set -eu

REPO_BASE=https://repo.etawen.dev
KEY_URL=$REPO_BASE/key.asc
KEY_FP_LONG=E40FB2409C9AD5243762294293AB12C4159FEDAB
KEY_FP_SHORT=93AB12C4159FEDAB

color() { printf '\033[%sm%s\033[0m' "$1" "$2"; }
say()   { printf '%s %s\n' "$(color '36;1' '==>')" "$*"; }
warn()  { printf '%s %s\n' "$(color '33;1' '!!')" "$*" >&2; }
die()   { printf '%s %s\n' "$(color '31;1' 'ERROR:')" "$*" >&2; exit 1; }

require_root() {
    if [ "$(id -u)" -ne 0 ]; then
        if command -v sudo >/dev/null 2>&1; then
            say "re-running as root via sudo"
            exec sudo -E sh "$0" "$@"
        fi
        die "must run as root (or have sudo installed)"
    fi
}

detect_pm() {
    if   command -v pacman >/dev/null 2>&1; then echo pacman
    elif command -v dnf    >/dev/null 2>&1; then echo dnf
    elif command -v apt    >/dev/null 2>&1; then echo apt
    else die "no supported package manager found (pacman / apt / dnf)"; fi
}

install_pacman() {
    say "adding etawen-ps5 to /etc/pacman.conf"
    if grep -q '^\[ps5\]' /etc/pacman.conf; then
        warn "[ps5] section already in /etc/pacman.conf — skipping"
    else
        printf '\n[ps5]\nServer = %s/arch\n' "$REPO_BASE" >> /etc/pacman.conf
    fi
    say "importing signing key $KEY_FP_SHORT into pacman keyring"
    # Containers / minimal installs may not have a local pacman signing
    # master key (pacman-key --lsign-key needs one). The check is "does the
    # gpg secret keyring under /etc/pacman.d/gnupg have any private keys".
    # pacman-key --init is idempotent so running it unconditionally is safe.
    if ! gpg --homedir /etc/pacman.d/gnupg --list-secret-keys >/dev/null 2>&1 \
         || [ -z "$(gpg --homedir /etc/pacman.d/gnupg --list-secret-keys 2>/dev/null)" ]; then
        say "pacman keyring uninitialized — running pacman-key --init + --populate"
        pacman-key --init >/dev/null 2>&1
        pacman-key --populate archlinux >/dev/null 2>&1 || true
    fi
    curl -fsSL "$KEY_URL" | pacman-key --add - >/dev/null
    pacman-key --lsign-key "$KEY_FP_SHORT" >/dev/null
    say "refreshing pacman databases"
    pacman -Sy --noconfirm >/dev/null
    say "done. install with:  pacman -S linux-ps5 ps5-linux-mwifiex ps5-linux-tools ps5-payload-sdk"
}

install_apt() {
    say "fetching signing key into /etc/apt/keyrings/etawen-ps5.gpg"
    install -d -m 0755 /etc/apt/keyrings
    curl -fsSL "$KEY_URL" | gpg --dearmor --yes -o /etc/apt/keyrings/etawen-ps5.gpg
    say "writing /etc/apt/sources.list.d/etawen-ps5.list"
    printf 'deb [signed-by=/etc/apt/keyrings/etawen-ps5.gpg] %s/deb ./\n' "$REPO_BASE" \
        > /etc/apt/sources.list.d/etawen-ps5.list
    say "running apt update"
    apt-get update >/dev/null
    say "done. install with:  apt install linux-ps5 ps5-linux-mwifiex ps5-linux-tools ps5-payload-sdk"
}

install_dnf() {
    say "fetching signing key into /etc/pki/rpm-gpg/RPM-GPG-KEY-etawen-ps5"
    install -d -m 0755 /etc/pki/rpm-gpg
    curl -fsSL "$KEY_URL" -o /etc/pki/rpm-gpg/RPM-GPG-KEY-etawen-ps5
    say "writing /etc/yum.repos.d/etawen-ps5.repo"
    cat > /etc/yum.repos.d/etawen-ps5.repo <<REPO
[etawen-ps5]
name=Etawen PS5 repo
baseurl=$REPO_BASE/rpm/
enabled=1
gpgcheck=0
repo_gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-etawen-ps5
REPO
    # On bazzite-atomic the dnf metadata cache is rpm-ostree-owned; refresh
    # via rpm-ostree if present (dnf clean expire-cache works otherwise).
    if command -v rpm-ostree >/dev/null 2>&1 && [ -d /var/cache/rpm-ostree ]; then
        say "refreshing rpm-ostree metadata"
        rm -rf /var/cache/rpm-ostree/repomd/etawen-ps5* 2>/dev/null || true
    else
        say "refreshing dnf metadata"
        dnf clean expire-cache >/dev/null 2>&1 || true
    fi
    INSTALL_HINT="dnf install --setopt=gpgcheck=0 linux-ps5 ps5-linux-mwifiex ps5-linux-tools ps5-payload-sdk"
    # Bazzite has two possible states:
    #   1. real ostree boot (upstream bazzite install)   -> rpm-ostree install
    #   2. our PS5 kexec boot (ostree deploy stripped) -> dnf5 install + sysrq
    # /run/ostree-booted is present iff (1). On (2) the /usr/bin/dnf shell
    # wrapper points users at docs and refuses install, so hit dnf5 direct;
    # systemctl reboot is also swallowed by the rpm-ostree-systemctl wrapper,
    # so use kernel-level sysrq to actually reboot.
    if grep -q '^VARIANT_ID=bazzite' /etc/os-release 2>/dev/null; then
        if [ -e /run/ostree-booted ]; then
            INSTALL_HINT="rpm-ostree install ps5-linux-mwifiex ps5-linux-tools && dnf upgrade -y linux-ps5 --setopt=gpgcheck=0 && systemctl reboot"
        else
            INSTALL_HINT="dnf5 install -y --setopt=gpgcheck=0 linux-ps5 ps5-linux-mwifiex ps5-linux-tools ps5-payload-sdk && sudo sync && sudo sh -c 'echo b > /proc/sysrq-trigger'"
        fi
    fi
    say "done. install with:  $INSTALL_HINT"
}

main() {
    require_root "$@"
    pm=$(detect_pm)
    say "detected package manager: $pm"
    case "$pm" in
        pacman) install_pacman ;;
        apt)    install_apt    ;;
        dnf)    install_dnf    ;;
    esac
}

main "$@"
