#!/usr/bin/env bash
set -Eeuo pipefail

# ---- Emby library interface for get.sh (no side effects when EMBY_LIB_ONLY is set) ----
if [[ -n "${EMBY_LIB_ONLY:-}" ]]; then
  # Disable error trapping in library mode so functions can return non-zero cleanly
  set +eE
  trap - ERR
  # repo registration check: looks for a section header in pacman.conf
  emby_repo_is_registered() {
    local channel="${1:?stable|beta}"
    local pc="/etc/pacman.conf"
    grep -qE "^\[emby-${channel}\]" "$pc"
  }
  # install/repair delegate to this script's normal behavior
  emby_repo_install() {
    local channel="${1:?}"; local sudo_cmd="${2:-sudo}"
    # Important: unset EMBY_LIB_ONLY when spawning the installer so it runs full mode
    if [[ $EUID -eq 0 || -z "${sudo_cmd}" ]]; then
      env -u EMBY_LIB_ONLY ch="$channel" bash "$BASH_SOURCE"
    else
      "$sudo_cmd" env -u EMBY_LIB_ONLY ch="$channel" bash "$BASH_SOURCE"
    fi
    return $?
  }
  emby_repo_repair() { emby_repo_install "$@"; }
  # drop: remove the repo section from pacman.conf and refresh DBs
  emby_repo_drop() {
    local channel="${1:?}"; local sudo_cmd="${2:-sudo}"
    local pc="/etc/pacman.conf"
    local tmp="${pc}.new.$$"
    $sudo_cmd awk -v name="emby-$channel" '
      BEGIN{inblk=0}
      {
        if (inblk) {
          if ($0 ~ /^\[/) { inblk=0; print }
          next
        }
        if ($0 ~ ("^\\[" name "\\]")) { inblk=1; next }
        print
      }' "$pc" > "$tmp"
    $sudo_cmd cp -p "$pc" "${pc}.bak.$(date +%s)" || true
    $sudo_cmd mv "$tmp" "$pc"
    $sudo_cmd pacman -Syy --noconfirm || true
  }
  # app helpers
  emby_app_is_installed() {
    if pacman -Qi "${1:?}" >/dev/null 2>&1; then
      return 0
    else
      return 1
    fi
  }
  emby_app_install() {
    local pkg="${1:?}"; local _ch="${2:-stable}"; local sudo_cmd="${3:-sudo}"
    # Ensure package database is up to date before install
    $sudo_cmd pacman -Sy --noconfirm || true
    $sudo_cmd pacman -S --needed --noconfirm "$pkg"
  }
  emby_app_uninstall() { local pkg="${1:?}"; local sudo_cmd="${2:-sudo}"; $sudo_cmd pacman -Rns --noconfirm "$pkg"; }
  emby_app_view_info() { pacman -Si "${1:?}" || true; }
  emby_app_open_software_center() { xdg-open "appstream://${1:?}"; }
  emby_app_get_installed_version() {
    local pkg="${1:?}"
    pacman -Q "$pkg" 2>/dev/null | awk '{print $2}' || echo ""
  }
  emby_app_list_available_versions() {
    local pkg="${1:?}"; local channel="${2:-stable}"
    local repo="emby-$channel"
    # Arch repos typically only keep latest version
    # Strip epoch (before :) and release (after last -) from version string
    # Format: [epoch:]version-release -> version
    pacman -Sl "$repo" 2>/dev/null | grep "^$repo $pkg " | awk '{
      ver=$3
      # Remove epoch if present (everything before :)
      if (index(ver, ":") > 0) {
        sub(/^[^:]+:/, "", ver)
      }
      # Remove release (everything after last -)
      sub(/-[^-]+$/, "", ver)
      print ver
    }' || echo ""
  }
  # Catalog: package_id|name|has_appstream
  emby_catalog_list() {
    local channel="${1:?stable|beta}"
    local repo="emby-$channel"
    # List packages from the Emby repo for current arch
    local catalog_pkg="emby-pac-${channel}"
    pacman -Sl "$repo" 2>/dev/null | awk -v r="$repo" '$1==r {print $2}' | while read -r p; do
      # hide catalog meta package from app list
      [[ "$p" == "$catalog_pkg" ]] && continue
      [ -n "$p" ] || continue
      local has="N"
      local name=""
      if command -v appstreamcli >/dev/null 2>&1; then
        name="$(appstreamcli get "$p" 2>/dev/null | awk -F': ' "/^Name:/{print \$2; exit}")"
        if [[ -n "$name" ]]; then
          has="Y"
        fi
      fi
      if [[ -z "$name" ]]; then
        name="$(printf '%s\n' "$p" | tr '-' ' ' | awk '{for(i=1;i<=NF;i++){ $i=toupper(substr($i,1,1)) substr($i,2)}; print}')"
      fi
      echo "$p|$name|$has"
    done
  }
  # Stubs for per-package block helpers (no-op on pacman)
  emby_pkg_is_blocked() {
    # Blocking not supported on pacman; always report "not blocked".
    return 1
  }
  emby_pkg_block_updates() {
    # No-op stub for pacman; succeed without changing anything.
    return 0
  }
  emby_pkg_unblock_updates() {
    # No-op stub for pacman; succeed without changing anything.
    return 0
  }
  # When sourced as a library, return to caller; if executed directly, exit quietly
  return 0 2>/dev/null || exit 0
fi

# Determine pacman arch string
arch="$(uname -m)"
case "$arch" in
  x86_64) arch="x86_64" ;;
  aarch64|arm64) arch="aarch64" ;;
  *)
    echo "Unsupported architecture: ${arch}" >&2
    exit 1
    ;;
esac

channel="${ch:-stable}"
REPO_NAME="emby-${channel}"
SERVER_URL="https://pkg.emby.media/pac/${channel}/os/$arch"
KEY_URL="https://pkg.emby.media/keys/emby-public.asc"
CATALOG_PKG="emby-pac-${channel}"
SIGLEVEL="Required DatabaseRequired"

# must be root
if [[ ${EUID:-$(id -u)} -ne 0 ]]; then
  echo "Please run as root (e.g. curl ... | sudo bash)" >&2
  exit 1
fi

command -v pacman >/dev/null || { echo "pacman not found (this script is for Arch/derivatives)"; exit 1; }
command -v curl >/dev/null   || { echo "curl is required"; exit 1; }

# init pacman-key ring if needed
if ! pacman-key --list-keys >/dev/null 2>&1; then
  pacman-key --init
fi

# fetch key to temp, extract fingerprint, import + locally sign
tmpkey="$(mktemp)"
trap 'rm -f "$tmpkey"' EXIT
curl -fsSL "$KEY_URL" -o "$tmpkey"

# pacman-key needs the key added to its keyring
pacman-key --add "$tmpkey"

# derive fingerprint from the ASCII key and lsign it so pacman trusts it
FPR="$(gpg --show-keys --with-colons "$tmpkey" | awk -F: "/^fpr:/ {print \$10; exit}")"
pacman-key --lsign-key "$FPR"

# Migration: Remove old generic repo names (stable/beta) if present
PC="/etc/pacman.conf"
OLD_REPO_NAME="${channel}"
if grep -qE "^\[${OLD_REPO_NAME}\]" "$PC" && [[ "$OLD_REPO_NAME" != "$REPO_NAME" ]]; then
  echo "Migrating from old repo name [${OLD_REPO_NAME}] to [${REPO_NAME}]..."
  cp -a "$PC" "${PC}.bak.migration.$(date +%s)"
  awk -v old="$OLD_REPO_NAME" '
    BEGIN{inblk=0}
    {
      if (inblk) {
        if ($0 ~ /^\[/) { inblk=0; print }
        next
      }
      if ($0 ~ ("^\\[" old "\\]")) { inblk=1; next }
      print
    }' "$PC" > "${PC}.new"
  mv "${PC}.new" "$PC"
fi

# add or update repo stanza in /etc/pacman.conf
if grep -qE "^\[${REPO_NAME}\]" "$PC"; then
  # update existing block only if the Server differs
  if ! awk -v name="$REPO_NAME" -v srv="$SERVER_URL" '
      $0 ~ ("^\\[" name "\\]") { f=1 }
      f && $0 ~ /^Server[[:space:]]*=/ { if ($0 ~ srv) ok=1; f=0 }
      END { exit ok ? 0 : 1 }' "$PC"; then
    cp -a "$PC" "${PC}.bak.$(date +%s)"
    awk -v name="$REPO_NAME" -v srv="$SERVER_URL" -v sig="$SIGLEVEL" '
      BEGIN{RS=""; ORS=""; FS="\n"} 
      {
        updated=0
        for (i=1;i<=NF;i++){
          if ($i ~ ("^\\[" name "\\]")) {
            print "["name"]\nServer = "srv"\nSigLevel = "sig"\n\n"
            # skip until next section
            for (j=i+1;j<=NF;j++){ if ($j ~ /^\[/){break} }
            for (k=j;k<=NF;k++) print $k"\n"
            updated=1
            break
          }
        }
        if(!updated) print
      }' "$PC" > "${PC}.new"
    mv "${PC}.new" "$PC"
  fi
else
  {
    echo ""
    echo "[${REPO_NAME}]"
    echo "Server = ${SERVER_URL}"
    echo "SigLevel = ${SIGLEVEL}"
    echo ""
  } >> "$PC"
fi

# refresh package databases
pacman -Syy --noconfirm

# If KDE Plasma is present, install PackageKit integration and enable the service
if command -v plasmashell >/dev/null 2>&1 || pacman -Qi plasma-workspace >/dev/null 2>&1; then
  echo "Detected KDE Plasma; installing PackageKit integration..."
  pacman -S --noconfirm --needed packagekit-qt6 packagekit appstream polkit-kde-agent || {
    echo "Warning: failed to install KDE PackageKit integration packages" >&2
  }
  if command -v systemctl >/dev/null 2>&1; then
    systemctl enable --now packagekit || {
      echo "Warning: failed to enable/start packagekit.service" >&2
    }
  fi
fi

# install catalog package (so Software/Discover see Emby entries)
if ! pacman -Qi "$CATALOG_PKG" >/dev/null 2>&1; then
  pacman -S --noconfirm --needed "$CATALOG_PKG" || {
    echo "Warning: failed to install ${CATALOG_PKG}. You can install it later with: pacman -S ${CATALOG_PKG}" >&2
  }
fi

# refresh AppStream cache if available
if command -v appstreamcli >/dev/null 2>&1; then
  appstreamcli refresh-cache --system --force >/dev/null 2>&1 || true
fi

# verify repo stanza exists in pacman.conf
if ! grep -qE "^\[${REPO_NAME}\]" "/etc/pacman.conf"; then
  echo "Error: repository '${REPO_NAME}' not present in /etc/pacman.conf" >&2
  exit 1
fi

echo "✅ Repo '${REPO_NAME}' is configured (Server=${SERVER_URL})."
echo "You can now install packages, e.g.:  pacman -S emby-server"
