#!/bin/bash
#set -x
source /etc/libretools.conf
source $(dirname $0)/libremessages
source $XDG_CONFIG_HOME/libretools/libretools.conf >/dev/null 2>&1|| true

# End inmediately but print a useful message
trap_exit() {
  error "($(basename $0)) $@"
  exit 1
}

# Trap signals from makepkg
set -E
trap 'trap_exit "TERM signal caught. Exiting..."' TERM HUP QUIT
trap 'trap_exit "Aborted by user! Exiting..."' INT
trap 'trap_exit "An unknown error has occurred. Exiting..."' ERR

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

}

# Add line to build order cache in CSV format
# $1 status
# $2 pkgname
add_order() {
  echo "${1};${DEPTH};${2:-${pkgbase}};${fullver};${PWD}" >> "${BUILDORDER}"
  ${VERBOSE} && msg2 "%${DEPTH}s${2:-${pkgbase}} [${1}]" || true
}

# Finds a PKGBUILD on toru's path cache
# Look in all caches but pick the first one
# TODO move to a toru flag (-p?)
where_is() {
  grep -m1 "^${1}:" "${TORUPATH}/paths" 2>/dev/null| \
    cut -d: -f2 2>/dev/null
}

if [ ! -f PKGBUILD ]; then
  error "Missing PKGBUILD"
  exit 1
fi

if ! source PKGBUILD ; then
  error "Can't source PKGBUILD"
  exit 1
fi

# Save resources
unset pkgdesc arch license groups backup install md5sums sha1sums \
      sha256sums source options >/dev/null 2>&1

unset build package >/dev/null 2>&1

for _pkg in ${pkgname[@]}; do
  unset package_${_pkg} >/dev/null 2>&1 || true
done
## 

# Get useful values
pkgbase="${pkgbase:-${pkgname[0]}}"
fullver=$(get_fullver ${epoch:-0} ${pkgver} ${pkgrel})

# Get or set the work dir
BUILDDIR="${1:-$(mktemp -d /tmp/${pkgbase}-treepkg-XXXx)}"
BUILDORDER="${BUILDDIR}/BUILDORDER"
DEPTH=${2:-0}
NEXTDEPTH=$((${DEPTH} + 1))
# This can be set as env vars (ie: $ V=false B=false treepkg)
# TODO Turn into flags?
VERBOSE=${V:-true}
BUILD=${B:-true}

# ensure it exists
touch "${BUILDORDER}"

# If this package is already built quit silently
if is_built "${pkgbase}" "${fullver}"; then
  add_order "ignore"
  exit 0
fi

# Ignore if already in build order
egrep -q ";${pkgbase};" "${BUILDORDER}" && exit 0

# Add pkgbase to build order
add_order "build"

# Copy the directory to the build dir
# TODO run makepkg --source to avoid moving garbage around?
cp -r "${PWD}" "${BUILDDIR}/$(printf "%03d" ${DEPTH})_${pkgbase}"

# Cleanup dep versioning
deps=($(echo "${depends[@]} ${makedepends[@]}" | \
       sed "s/[=<>]\+[^ ]\+//g" | \
       tr ' ' "\n" | \
       sort -u))

# NOTE: getting depends from package() is a PITA
for _dep in ${deps[@]}; do
# Ignore if already in build order
# TODO move deps deeper in the tree if
# pkgbase - dep1
#         \ dep2 - dep1
# dep1 should be depth + 1
  egrep -q ";${_dep};" "${BUILDORDER}" && continue

# Ask toru where's a PKGBUILD
  depdir="$(where_is ${_dep})"

  if [ -z "${depdir}" -o ! -d "${depdir}" ]; then
# We specify the pkgname because we can't source the dep PKGBUILD
# Normally 'any' packages are missing from our work ABS
    add_order "missing" "${_dep}"
    continue
  fi

  pushd "${depdir}" >/dev/null

# Run itself over dependencies
  $0 "${BUILDDIR}" ${NEXTDEPTH}

done

# Only build at the end
if [ ${DEPTH} -eq 0 ]; then
  ${VERBOSE} && msg "Starting build" || true

  if ${BUILD}; then
    ${VERBOSE} && msg "Build tree stored in ${BUILDORDER}" || true

# Build everything sorting the build dir
# The reverse order ensures we start by the deepest packages
    for _pkg in $(ls -r "${BUILDDIR}"); do
# Ignore if there's no PKGBUILD
      if [ ! -f "${BUILDDIR}/${_pkg}/PKGBUILD" ]; then continue; fi

      ${VERBOSE} && msg "Building ${_pkg/_/ }" || true

# Run build command
      pushd "${BUILDDIR}/${_pkg}" >/dev/null
        ${FULLBUILDCMD}
      popd >/dev/null
    done

  else
# Just print the working dir
    ${VERBOSE} || echo "${BUILDORDER}" || true
  fi

fi

exit $?