#!/usr/bin/env bash

set -euo pipefail

# --- Helper functions ---
log() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
exists() { command -v "$1" >/dev/null 2>&1; }

# --- Defined Paths ---
PANAMA_PATH="$HOME/.local/share/Panama"

echo -e "\n--- Installing Repositories ---"
log "Installing RPM Fusion Free and Nonfree Repositories"
sudo dnf install -y https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm > /dev/null
log "Enabling Fedora Cisco OpenH264 Repository"
sudo dnf config-manager setopt fedora-cisco-openh264.enabled=1
log "Installing RPM Fusion AppStream Metadata"
sudo dnf update @core -y > /dev/null
sudo dnf install -y rpmfusion-\*-appstream-data > /dev/null
log "Installing Terra Repository"
sudo dnf install -y --nogpgcheck --repofrompath 'terra,https://repos.fyralabs.com/terra$releasever' terra-release > /dev/null

echo -e "\n--- Installing relevant packages ---"
log "Updating all packages. This may take a while"
sudo dnf update -y --refresh > /dev/null

log "Updating core, multimedia, and sound-and-video groups"
# A trailing `&& sync` here previously meant a failing groupupdate was exempt
# from set -e (bash does not apply -e to the left side of a && list), so the
# failure went unreported. Sync unconditionally on its own line instead.
sudo dnf4 groupupdate -y 'core' 'multimedia' 'sound-and-video' \
    --setop='install_weak_deps=False' \
    --exclude='PackageKit-gstreamer-plugin' \
    --allowerasing > /dev/null
sync
log "Swapping ffmpeg-free for ffmpeg"
sudo dnf swap -y 'ffmpeg-free' 'ffmpeg' --allowerasing > /dev/null
log "Swapping mesa-va-drivers for mesa-va-drivers-freeworld"
sudo dnf swap -y mesa-va-drivers mesa-va-drivers-freeworld > /dev/null
log "Upgrading Multimedia group with optional packages"
sudo dnf4 group upgrade -y --with-optional Multimedia > /dev/null
log "Installing GStreamer plugins (bad, good, base)"
sudo dnf install -y gstreamer1-plugins-{bad-\*,good-\*,base} \
    --exclude=gstreamer1-plugins-bad-free-devel > /dev/null

# --- Install all initial packages ---
PACKAGES_FILE="$PANAMA_PATH/setup/packages/initial-packages"
if [[ -f "$PACKAGES_FILE" ]]; then
	INITIAL_PACKAGES=$(tr "\n" " " <"$PACKAGES_FILE")
	log "Installing Initial Packages"
  echo -e "Includes the following packages:"
  echo -e "$(<"$PACKAGES_FILE")"
	sudo dnf install -y $INITIAL_PACKAGES > /dev/null
	log "Initial packages installed!"
else
	log "Package list was not in specified path: $PACKAGES_FILE"
fi

# --- Install Desktop Packages ---
DESKTOP_FILE="$PANAMA_PATH/setup/packages/desktop-packages"
if [[ -f "$DESKTOP_FILE" ]]; then
	DESKTOP_PACKAGES=$(tr "\n" " " <"$DESKTOP_FILE")
	log "Installing Desktop Packages"
  echo -e "Includes the following packages:"
  echo -e "$(<"$DESKTOP_FILE")"
	sudo dnf install -y $DESKTOP_PACKAGES > /dev/null
	log "Desktop packages installed!"
else
	log "Package list was not in specified path: $DESKTOP_FILE"
fi

# --- Install Development Packages needed for Neovim ---
DEV_FILE="$PANAMA_PATH/setup/packages/development-packages"
if [[ -f "$DEV_FILE" ]]; then
	DEV_PACKAGES=$(tr "\n" " " <"$DEV_FILE")
	log "Installing Development Packages. Mostly for Neovim."
  echo -e "Includes the following packages:"
  echo -e "$(<"$DEV_FILE")"
  sudo dnf install -y $DEV_PACKAGES > /dev/null
	log "Development packages installed!"
else
	log "Package list was not in specified path: $DEV_FILE"
fi

# --- Install the Hyprland desktop ---
# Most of these live in the lionheartp/Hyprland COPR rather than Fedora proper.
HYPR_FILE="$PANAMA_PATH/setup/packages/hyprland-packages"
if [[ -f "$HYPR_FILE" ]]; then
	log "Enabling Hyprland COPR"
	sudo dnf copr enable -y lionheartp/Hyprland > /dev/null
	HYPR_PACKAGES=$(tr "\n" " " <"$HYPR_FILE")
	log "Installing Hyprland desktop packages"
	echo -e "Includes the following packages:"
	echo -e "$(<"$HYPR_FILE")"
	sudo dnf install -y --setopt=install_weak_deps=False $HYPR_PACKAGES > /dev/null
	log "Hyprland packages installed!"
else
	log "Package list was not in specified path: $HYPR_FILE"
fi

# --- Applications no repository packages -------------------------------------
#
# Everything else Panama installs comes from dnf or Flathub. These three do not
# exist in either, so each is an explicit exception with a reason, and each is
# skipped when already present so a re-run costs nothing.
#
# None of them pins a version. sunhat pinned URLs -- upscayl 2.11.5, LACT 0.5.4,
# a fedora-40 RPM -- and every one of them was a 404 within a release cycle. An
# installer that resolves "latest" keeps working; one that names a version rots.
#
# A failure here is logged and stepped over rather than aborting: this stage has
# already installed the desktop by this point, and an unreachable third-party
# host should not cost you that.

# Bun: the JavaScript runtime and package manager. No RPM, no flatpak.
if [[ -x "$HOME/.bun/bin/bun" ]]; then
  log "Bun already installed at \"$HOME/.bun/bin/bun\""
else
  log "Installing Bun via curl..."
  curl -fsSL https://bun.sh/install | bash > /dev/null 2>&1 || log "Bun install failed; skipping"
fi

# Claude Code: Anthropic's CLI. The official installer keeps itself updated
# afterwards, so this runs once and then never needs to again.
if command -v claude >/dev/null 2>&1; then
  log "Claude Code already installed at \"$(command -v claude)\""
else
  log "Installing Claude Code via the official installer..."
  curl -fsSL https://claude.ai/install.sh | bash > /dev/null 2>&1 || log "Claude Code install failed; skipping"
fi

# RustDesk: remote desktop. The flatpak cannot register the root-owned system
# service that unattended access needs -- see panama-doctor's rustdesk check --
# so this takes the RPM. The download URL is resolved from the latest release
# rather than written down, so it does not go stale.
if rpm -q rustdesk >/dev/null 2>&1; then
  log "RustDesk already installed"
else
  log "Resolving the latest RustDesk release..."
  rustdesk_url="$(curl -fsSL https://api.github.com/repos/rustdesk/rustdesk/releases/latest 2>/dev/null \
    | jq -r '.assets[].browser_download_url | select(test("x86_64\\.rpm$")) | select(test("suse") | not)' \
    | head -1)"
  if [[ -n "$rustdesk_url" ]]; then
    log "Installing RustDesk from $rustdesk_url"
    # The RPM ships rustdesk.service already enabled, which is what provides
    # unattended access; Panama deliberately does not start it a second time.
    sudo dnf install -y "$rustdesk_url" > /dev/null || log "RustDesk install failed; skipping"
  else
    log "Could not resolve a RustDesk release; skipping"
  fi
fi

# --- Install Flatpak Packages ---
FLATPAK_FILE="$PANAMA_PATH/setup/packages/flatpak-packages"
if [[ -f "$FLATPAK_FILE" ]]; then
	FLATPAK_PACKAGES=$(tr "\n" " " <"$FLATPAK_FILE")
	log "Adding Flathub remote"
	sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo > /dev/null
	log "Installing Flatpak Packages"
	echo -e "Includes the following packages:"
	echo -e "$(<"$FLATPAK_FILE")"
	sudo flatpak install -y flathub $FLATPAK_PACKAGES > /dev/null
	log "Flatpak packages installed!"
else
	log "Package list was not in specified path: $FLATPAK_FILE"
fi
