#!/bin/bash
# Queries the ABS
# License: GPL3

## TODO
# * Add license text
# * Create symlinks from pkgbase to pkgname[@] for easy package finding
# * Use lastsync to store processed packages

## GOALS
# * Have a searchable database of PKGBUILD metadata
# * Have an interface for source-only builds
# * Possibility to hook up ABS dirs besides ABSROOT (low priority)
# * Tell updates and non available binary packages (working on this)

source /etc/abs.conf
source /etc/libretools.conf
source /etc/libretools.d/prtools.conf

# Stores the lastsync date
lastsync() {
  [ -e ${lastsyncfile} -a ! -w ${lastsyncfile} ] && {
      error "The sync date can't be saved. ${lastsyncfile} isn't writable."
      return 1
  }

  date +%s > "$lastsyncfile"
  touch "$lastsyncfile"
}

##
#  usage : get_full_version( $epoch, $pkgver, $pkgrel )
# return : full version spec, including epoch (if necessary), pkgver, pkgrel
##
get_full_version() {
    if [[ $1 -eq 0 ]]; then
        # zero epoch case, don't include it in version
        echo $2-$3
    else
        echo $1:$2-$3
    fi
}

# Outputs an ordered package-fullpkgver array 
print_package_array() {
  echo "$@" | tr " " "\n" | sort -V -u
}


# Gets repo.db contents
# $1 repo
get_db_contents() {
  [ ! -r /var/lib/pacman/sync/$1.db ] && return 0

  bsdtar -tf /var/lib/pacman/sync/$1.db | \
    cut -d'/' -f1 | \
    sort -V -u
}


extract_pkgname() {
  echo "$@" | tr " " "\n" | sed "s/^\(.\+\)-[^-]\+-[^-]\+$/\1/"
}

extract_fullpkgver() {
  echo "$@" | tr " " "\n" | sed "s/^.\+-\([^-]\+-[^-]\+\)$/\1/"
}


# Updates the database by finding all PKGBUILDS
# Workflow:
# * Find all PKGBUILDs on the ABS repo specified
# * Get all packages already on package repos
# * Compare them
# Args:
update() {
# The PKGBUILDs found
  local pkgbuilds=()
# The list of pkgname-fullpkgver
  local packages_to_sync=()
  local packages_in_sync=()
  local needed_updates=()
  local old_versions=()

# Find all the PKGBUILDs newer than the last update
# Update newer, otherwise everything
  if [ $force ] || [ ! -e ${lastsyncfile} ]; then
      $quiet || msg "Forcing upgrade"
      pkgbuilds=($(find ${@} -maxdepth 2 -type f -name 'PKGBUILD'))
  else
      pkgbuilds=($(find ${@} -maxdepth 2 -type f -name 'PKGBUILD' -newer ${lastsyncfile}))
  fi

# Inform how many PKGBUILDS were found and quit immediately if none
  $quiet || msg "Found $((${#pkgbuilds[*]}-1)) packages to update"
  [ ${#pkgbuilds[*]} -eq 1 ] && {
      $quiet || msg2 "There's nothing to be done. Phew!"
      exit 0
  }

  for _pkgbuild in ${pkgbuilds[@]}; do

# The repo name is guessed
# You *must* use repo/pkgbase structure
    _pkgpath=$(dirname "${_pkgbuild}")
    _pkgbase=$(basename "${_pkgpath}")
    _pkgrepo=$(basename $(dirname "${_pkgpath}"))

    source ${_pkgbuild}

    for _pkg in ${pkgname[@]}; do
# Fill the list of packages to find
      packages_to_sync+=($_pkg-$(get_full_version ${epoch:-0} $pkgver $pkgrel))
    done

    unset pkgbase pkgname pkgver pkgrel source epoch
  done

# Get repo database contents
  packages_in_sync=($(get_db_contents ${_pkgrepo}))
  print_package_array "${packages_to_sync[@]}" > ${TMPDIR}/packages_to_sync
  print_package_array "${packages_in_sync[@]}" > ${TMPDIR}/packages_in_sync

# We've orderer the files!
  needed_updates=($(comm --nocheck-order -32 ${TMPDIR}/packages_to_sync ${TMPDIR}/packages_in_sync))
  old_versions=($(comm --nocheck-order -31 ${TMPDIR}/packages_to_sync ${TMPDIR}/packages_in_sync))

  $quiet || msg "This packages are available to update"
  for _update in ${needed_updates[@]}; do
    pkg=$(extract_pkgname $_update)

    $quiet && echo $pkg
    $quiet || {
      ver=$(extract_fullpkgver $_update)
      oldver=$(extract_fullpkgver $(grep -w $pkg ${TMPDIR}/packages_in_sync))

      msg2 "$pkg $oldver => $ver"
    }

  done

#  lastsync

}

## MAIN
commands=()
repos=()
quiet=false
force=false
while getopts 'hqfu' arg; do
  case $arg in
    h) usage; exit 0 ;;
    q) quiet=true ;;
    f) force=true ;;
    u) commands+=(update);;
  esac

  shift $((OPTIND-1))
done

# This is the syncfile, stores the last date as content and mtime
lastsyncfile=${ABSROOT}/toru.lastsync

TMPDIR=$(mktemp -d)

[[ -z ${TMPDIR} ]] && exit 1

${commands[0]} ${@}

rm -rf ${TMPDIR}

exit $?