#!/usr/bin/env bash
# Copyright (C) 2025 CachyOS
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

function error() {
    echo "Error: $*" >&2
}
function die() {
    error "$@"
    exit 1
}

if ((EUID > 0)); then
    die "Run this script as root"
fi

if (($# < 1)); then
    die "Usage: $0 [package]..."
fi

function extract_package_modules() {
    local pkgname="$1"

    local tmp="$(mktemp --suffix="-extractor" -d)"
    trap 'rm -rf -- "$tmp"' RETURN

    # Import cachyos repository key
    local gpg_dir="$tmp/gnupg"
    local pacman_conf="$tmp/pacman.conf"
    mkdir -p "$gpg_dir"

    cat << 'EOF' >"$pacman_conf"
[options]
DisableDownloadTimeout
Architecture = auto

[cachyos]
Server = https://mirror.cachyos.org/repo/$arch/$repo
EOF

    local -a pacman_opts=(
       --gpgdir "$gpg_dir"
       --config "$pacman_conf"
    )

    # Workaround for DNS issues within the mkarchiso (chroot) environment
    # TODO: Find a better way to detect it
    local -i is_archiso=0
    if [ -f /etc/mkinitcpio.conf.d/archiso.conf ]; then
        is_archiso=1
        mv -f /etc/resolv.conf /etc/resolv.conf.bak
        echo "nameserver 1.1.1.1" > /etc/resolv.conf
    fi

    if ! (
        pacman-key "${pacman_opts[@]}" --init
        pacman-key "${pacman_opts[@]}" --recv-keys F3B607488DB35A47 --keyserver keyserver.ubuntu.com
        pacman-key "${pacman_opts[@]}" --lsign-key F3B607488DB35A47
    ); then
        error "Failed to import GPG key for cachyos repository"
        return 1
    fi

    if ! pacman -S "${pacman_opts[@]}" -sq "^$pkgname\$" &>/dev/null; then
        error "Package $pkgname is not found in any repository."
        error "Make sure your pacman configuration is correct."
        return 1
    fi

    echo "Downloading $pkgname package..."

    local url="$(pacman -Swd "${pacman_opts[@]}" --print "$pkgname")"
    curl -SOL --retry 5 --output-dir "$tmp" "$url" || {
        error "Failed to download $pkgname package"
        return 1
    }

    ((is_archiso)) && mv /etc/resolv.conf.bak /etc/resolv.conf

    cd "$tmp"
    echo "Unpacking $pkgname package..."
    tar -xf "$pkgname"-*.pkg.tar.zst || {
        error "Failed to extract package tarball"
        return 1
    }

    if [ ! -e "$tmp/usr/lib/modules" ]; then
        error "Package $pkgname doesn't contain any kernel modules"
        return 1
    fi

    mkdir -p "/usr/share/modules/$pkgname"
    cp -v "$tmp/usr/lib/modules"/*/extramodules/*.ko.zst "/usr/share/modules/$pkgname/"

    echo "Extracting modules for $pkgname is complete"
    return 0
}

for package; do
    extract_package_modules "$package"
done
