#!/usr/bin/env miaou-bash

# CONSTANTS

REFRESH_SLOT='24 hours'
DEBIAN_REPO_DIR='/var/lib/apt/lists/partial'
ARCH_REPO_DIR='/var/lib/pacman/sync'

# functions

function usage {
  echo "usage: $(basename "$0") <packages...>"
  echo 'idempotent package installation : install only if not yet done + smart refresh repositories'
}

# $1 -> file to compare with REFRESH_SLOT
function needs_refresh {
  [[ $(date --date="-$REFRESH_SLOT" +%s) -gt $(date -d "$(stat -c %y "$1")" +%s) ]]
}

function debian_update_repo {
  if needs_refresh "$DEBIAN_REPO_DIR"; then
    echo "updating repositories..."
    apt-get update
  fi
}

function debian_add {
  declare -a wanted=("$@")
  declare -a missing=()
  mapfile -t queries < <(dpkg-query -W -f='${Package}: ${Status}\n' "${wanted[@]}" 2>&1 || true)

  local unrecognized_regex='^dpkg-query: no packages found matching (.*)$'
  local missing_regex='(.*): .* not-installed$'
  for query in "${queries[@]}"; do
    if [[ "$query" =~ $unrecognized_regex ]]; then
      missing+=("${BASH_REMATCH[1]}")
    elif [[ "$query" =~ $missing_regex ]]; then
      missing+=("${BASH_REMATCH[1]}")
    fi
  done

  if [[ "${#missing[@]}" -gt 0 ]]; then
    debian_update_repo
    echo installing packages: "${missing[@]}"
    apt-get install -y "${missing[@]}"
  fi
}

function arch_update_repo {
  if needs_refresh "$ARCH_REPO_DIR"; then
    echo "updating repositories..."
    pacman -Syyu --noconfirm
  fi
}

function arch_add {
  declare -a wanted=("$@")
  declare -a missing=()
  for i in "${wanted[@]}"; do
    if ! pacman -Ql "$i" &>/dev/null; then
      missing+=("$i")
    fi
  done
  if [[ "${#missing[@]}" -gt 0 ]]; then
    arch_update_repo
    echo installing packages: "${missing[@]}"
    pacman -S --noconfirm "${missing[@]}"
  fi
}

# MAIN

[ "$UID" -ne 0 ] && echo 'root privilege required' && builtin exit 1
[[ $# -lt 1 ]] && usage && builtin exit 2

source "$MIAOU_BASH_DIR"/lib/functions.bash
DISTRO_LIKE=$(get_distro_like)
case "$DISTRO_LIKE" in
debian) debian_add "$@" ;;
arch) arch_add "$@" ;;
esac
