#!/usr/bin/env bash
# Select the CPU baseline for dsr-aur. Detection uses glibc's runtime CPU/OS checks,
# including AVX OS state, rather than assuming every x86_64 CPU can execute AVX2.
set -euo pipefail

profile_from_loader_help() {
  local output
  output=$(cat)
  if grep -q 'x86-64-v3 (supported, searched)' <<<"$output"; then echo v3; return 0; fi
  if grep -q 'x86-64-v2 (supported, searched)' <<<"$output"; then echo v2; return 0; fi
  return 1
}
supported_profile() {
  local loader output
  [[ $(uname -m) == x86_64 ]] || { echo 'Only x86_64 is supported.' >&2; return 1; }
  for loader in /lib/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2; do
    [[ -x $loader ]] || continue
    output=$(LC_ALL=C "$loader" --help)
    profile_from_loader_help <<<"$output" && return 0
  done
  echo 'This CPU does not support x86-64-v2; dsr-aur cannot be enabled safely.' >&2
  return 1
}

# shellcheck disable=SC2016 # $arch must stay literal for pacman to substitute.
profile_server() {
  case $1 in
    v2) echo 'https://aur.quantforge.com.br/v2/$arch' ;;
    v3) echo 'https://aur.quantforge.com.br/$arch' ;;
    *) return 1 ;;
  esac
}

# Rewrite only the dsr-aur section; keep all other repositories/options byte-for-byte.
# Reject duplicate sections rather than silently leaving a second active server.
render_config() {
  local source=$1 profile=$2
  awk -v server="$(profile_server "$profile")" '
    /^[[:space:]]*\[dsr-aur\][[:space:]]*$/ {
      if (++seen > 1) exit 2
      print "[dsr-aur]\nSigLevel = Required\nServer = " server
      inside=1; next
    }
    /^[[:space:]]*\[/ { inside=0 }
    !inside { print }
    END { if (!seen) print "\n[dsr-aur]\nSigLevel = Required\nServer = " server }
  ' "$source"
}

main() {
  local requested=${1:---detect} supported profile tmp backup url
  case $requested in
    --detect) supported_profile; return ;;
    --print) profile_server "$(supported_profile)"; return ;;
    --help|-h)
      echo 'Usage: dsr-aur-profile [--detect|--print|--configure [auto|v2|v3]]'
      echo 'Configure requires root; it validates the signed database before editing pacman.conf.'
      return ;;
    --configure) ;;
    *) echo 'Unknown option (see --help).' >&2; return 2 ;;
  esac
  [[ $EUID == 0 ]] || { echo 'Run with sudo: dsr-aur-profile --configure [auto|v2|v3]' >&2; return 1; }
  supported=$(supported_profile)
  profile=${2:-auto}
  [[ $profile != auto ]] || profile=$supported
  [[ $profile == v2 || $profile == v3 ]] || { echo 'Expected auto, v2 or v3.' >&2; return 2; }
  [[ $profile != v3 || $supported == v3 ]] || { echo 'This CPU cannot execute v3 packages.' >&2; return 1; }
  [[ ! -e /var/lib/pacman/db.lck ]] || { echo 'Pacman is running; try again later.' >&2; return 1; }
  tmp=$(mktemp -d)
  # shellcheck disable=SC2064 # Capture the quoted temp path now; main's locals are gone at EXIT.
  trap "rm -rf -- $(printf '%q' "$tmp")" EXIT
  url=$(profile_server "$profile")
  url=${url/\$arch/x86_64}
  curl --proto '=https' -fsSL --max-time 60 "$url/dsr-aur.db" -o "$tmp/db"
  curl --proto '=https' -fsSL --max-time 60 "$url/dsr-aur.db.sig" -o "$tmp/db.sig"
  pacman-key --verify "$tmp/db.sig" "$tmp/db"
  gpg --homedir /etc/pacman.d/gnupg --batch --status-fd 1 --verify "$tmp/db.sig" "$tmp/db" 2>/dev/null |
    grep -q '^\[GNUPG:\] VALIDSIG 527847CE99A97C4EEB1CA5394250FF48D2374AED '
  if (( $(pacman-conf --repo-list | grep -cx dsr-aur || true) > 1 )); then
    echo 'Duplicate dsr-aur repositories (possibly in Include files); resolve them first.' >&2
    return 1
  fi
  render_config /etc/pacman.conf "$profile" >"$tmp/pacman.conf"
  pacman-conf --config "$tmp/pacman.conf" --repo dsr-aur Server >/dev/null
  [[ $(pacman-conf --config "$tmp/pacman.conf" --repo-list | grep -cx dsr-aur) == 1 ]] || {
    echo 'dsr-aur is also defined by an Include file; resolve the duplicate first.' >&2
    return 1
  }
  # Explicit targets reinstall even when the selected profile's pkgrel is numerically
  # lower (v3 -> v2). Only reinstall packages actually supplied by this repository.
  # Syncing and installing always happens as a full upgrade, never a partial -Sy.
  local -a targets=(dsr-aur-client)
  local pkg listing available
  listing=$(tar -xOf "$tmp/db" --wildcards '*/desc')
  available=$(awk '$0 == "%NAME%" { getline; print }' <<<"$listing")
  while read -r pkg; do
    [[ $pkg == dsr-aur-client ]] && continue
    if grep -qxF "$pkg" <<<"$available"; then targets+=("$pkg"); fi
  done < <(pacman -Qq)
  grep -qxF dsr-aur-client <<<"$available" || { echo 'Selected repository has no dsr-aur-client yet.' >&2; return 1; }
  if ! cmp -s "$tmp/pacman.conf" /etc/pacman.conf; then
    backup=/etc/pacman.conf.dsr-aur.$(date +%Y%m%dT%H%M%S).bak
    cp -a /etc/pacman.conf "$backup"
    install -m 644 "$tmp/pacman.conf" /etc/pacman.conf
    echo "Backup: $backup"
  fi
  echo "Selected dsr-aur profile: $profile ($url)"
  echo 'Performing a full upgrade and replacing installed dsr-* packages with this profile.'
  pacman -Syu -- "${targets[@]/#/dsr-aur/}"
  rm -rf -- "$tmp"
  trap - EXIT
}

[[ ${DSR_SOURCE_ONLY:-0} == 1 ]] && return 0
main "$@"
