#!/bin/bash

# Print the logo
print_logo() {
    cat << "EOF"


 ██╗  ██╗ █████╗ ███╗   ███╗██████╗  █████╗  ██████╗██╗  ██╗
 ██║  ██║██╔══██╗████╗ ████║██╔══██╗██╔══██╗██╔════╝██║ ██╔╝
 ███████║███████║██╔████╔██║██████╔╝███████║██║     █████╔╝
 ██╔══██║██╔══██║██║╚██╔╝██║██╔═══╝ ██╔══██║██║     ██╔═██╗
 ██║  ██║██║  ██║██║ ╚═╝ ██║██║     ██║  ██║╚██████╗██║  ██╗
 ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝╚═╝     ╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝


EOF
}

# Clear screen and show logo
clear
print_logo

echo "Updating Arch..."
sudo pacman -Syu

echo "Updating AUR..."

if ! yay -Sua 2>/dev/null; then
    echo "yay -Sua returned an error. Let's rebuild YAY."
    sudo pacman -R yay
    cd /tmp
    git clone https://aur.archlinux.org/yay.git
    cd yay
    makepkg -si
    cd ..
    rm -rf yay
    cd
    yay -Sua --noconfirm
else
    yay -Sua --noconfirm
fi

HAMPACK_DIR="$HOME/.local/share/HamPack"
VERSION_FILE="$HOME/.local/state/HamPack/.installed_versions"
COMPILE_CONF="$HAMPACK_DIR/compile.conf"
BINARIES_CONF="$HAMPACK_DIR/binaries.conf"

echo "Pulling latest HamPack configuration..."
git -C "$HAMPACK_DIR" pull

# ── GitHub version helpers ────────────────────────────────────────────────────

github_repo_from_url() {
  local url="$1"
  if [[ "$url" =~ github\.com/([^/]+)/([^/]+) ]]; then
    echo "${BASH_REMATCH[1]}/${BASH_REMATCH[2]%.git}"
  fi
}

github_latest() {
  local repo="$1"
  curl -sf "https://api.github.com/repos/$repo/releases/latest" \
    | grep '"tag_name"' \
    | sed 's/.*"tag_name": *"\([^"]*\)".*/\1/' \
    | sed 's/^v//'
}

installed_version() {
  local app="$1"
  grep "^$app=" "$VERSION_FILE" 2>/dev/null | cut -d'=' -f2
}

# Update version= for an app in a conf file
set_conf_version() {
  local conf="$1" app="$2" new_version="$3"
  awk -v app="$app" -v ver="$new_version" '
    /^\[/ { in_app = ($0 == "[" app "]") }
    in_app && /^version=/ { print "version=" ver; next }
    { print }
  ' "$conf" > "$conf.tmp" && mv "$conf.tmp" "$conf"
}

# ── Check compiled apps (compile.conf) ───────────────────────────────────────

check_compiled() {
  echo ""
  echo "Checking compiled application versions..."
  local app="" version="" git_url="" wget_url=""

  while IFS= read -r line || [ -n "$line" ]; do
    [[ -z "$line" || "$line" == \#* ]] && continue

    if [[ "$line" =~ ^\[(.+)\]$ ]]; then
      _check_compiled_app "$app" "$version" "$git_url" "$wget_url"
      app="${BASH_REMATCH[1]}" version="" git_url="" wget_url=""
      continue
    fi

    local key="${line%%=*}" value="${line#*=}"
    case "$key" in
      version) version="$value" ;;
      git)     git_url="$value" ;;
      wget)    wget_url="$value" ;;
    esac
  done < "$COMPILE_CONF"

  _check_compiled_app "$app" "$version" "$git_url" "$wget_url"
}

_check_compiled_app() {
  local app="$1" version="$2" git_url="$3" wget_url="$4"
  [ -z "$app" ] && return

  local source_url="${git_url:-$wget_url}"
  local gh_repo
  gh_repo=$(github_repo_from_url "$source_url")

  if [ -z "$gh_repo" ]; then
    echo "  $app: manual check needed: $source_url"
    return
  fi

  local latest
  latest=$(github_latest "$gh_repo")

  if [ -z "$latest" ]; then
    echo "  $app: GitHub API unavailable, skipping"
    return
  fi

  local installed
  installed=$(installed_version "$app")
  local current="${installed:-$version}"

  if [ "$current" = "$latest" ]; then
    echo "  $app: up to date ($current)"
    return
  fi

  echo "  $app: $current -> $latest"

  if [ -n "$git_url" ]; then
    # git= apps: update version in conf and clear installed record so
    # install-compiled.sh rebuilds from the freshly cloned HEAD
    set_conf_version "$COMPILE_CONF" "$app" "$latest"
    sed -i "/^$app=/d" "$VERSION_FILE" 2>/dev/null
    echo "  $app: queued for rebuild"
  else
    echo "  $app: update available but URL is version-specific — update compile.conf manually"
  fi
}

# ── Check binary apps (binaries.conf) ────────────────────────────────────────

check_binaries() {
  echo ""
  echo "Checking binary application versions..."
  local app="" version="" url=""

  while IFS= read -r line || [ -n "$line" ]; do
    [[ -z "$line" || "$line" == \#* ]] && continue

    if [[ "$line" =~ ^\[(.+)\]$ ]]; then
      _check_binary_app "$app" "$version" "$url"
      app="${BASH_REMATCH[1]}" version="" url=""
      continue
    fi

    local key="${line%%=*}" value="${line#*=}"
    case "$key" in
      version) version="$value" ;;
      url)     url="$value" ;;
    esac
  done < "$BINARIES_CONF"

  _check_binary_app "$app" "$version" "$url"
}

_check_binary_app() {
  local app="$1" version="$2" url="$3"
  [ -z "$app" ] && return

  local gh_repo
  gh_repo=$(github_repo_from_url "$url")

  if [ -z "$gh_repo" ]; then
    echo "  $app: manual check needed: $url"
    return
  fi

  local latest
  latest=$(github_latest "$gh_repo")

  if [ -z "$latest" ]; then
    echo "  $app: GitHub API unavailable, skipping"
    return
  fi

  local installed
  installed=$(installed_version "$app")
  local current="${installed:-$version}"

  if [ "$current" = "$latest" ]; then
    echo "  $app: up to date ($current)"
  else
    echo "  $app: update available ($current -> $latest) — update binaries.conf to install"
  fi
}

# ── Main ─────────────────────────────────────────────────────────────────────

mkdir -p "$HOME/.local/state/HamPack"

check_compiled
check_binaries

echo ""
echo "Installing any new packages..."
source "$HAMPACK_DIR/utils.sh"
source "$HAMPACK_DIR/packages.conf"
install_packages "${UTILITIES[@]}"
install_packages "${APPLICATIONS[@]}"

echo "Installing any new Flatpaks..."
source "$HAMPACK_DIR/install-flatpaks.sh"

echo "Installing any new or updated compiled applications..."
bash "$HAMPACK_DIR/install-compiled.sh"

echo "Installing any new or updated pre-built binaries..."
bash "$HAMPACK_DIR/install-binaries.sh"

echo "Done. You probably want to reboot your system..."
