#!/usr/bin/env bash

die() {
    echo "ERROR: $@"
    exit 1
}

run() {
    echo "$@"
    "$@" || die "$?"
}

verbose=
vprint() {
    [[ -n ${verbose} ]] || return 0

    echo "$@"
}

usage() {
    echo "A tool to bump/commit haskell packages easily."
    echo "Needs to be ran in a bumped directory"
    echo ""
    echo "Usage: $0 [ --help ] [ --continue ] <pv | --auto> [rm-files...]"
    echo ""
    echo "    --continue     does not run 'hackport' if target ebuild is"
    echo "                   already created, but commits it's state."
    echo "                   Handy, when you've modified ebuild and lazy"
    echo "                   to type commit message."
    echo ""
    echo "Usage examples:"
    echo " \$ cd \${gentoo_haskell}/dev-haskell/tls"
    echo " \$ $0 --auto *.ebuild"
    echo "    or"
    echo " \$ USE=-profile HCFLAGS=-O0 $0 --auto *.ebuild"
    echo "    or even"
    echo " \$ FEATURES=\"-strict -stricter -test\" USE=-profile HCFLAGS=-O0 $0 --auto *.ebuild"
    die "no args"
}

find_prog() {
    local var_name=$1
    local prog_name=${!1}

    echo -n "Resolving ${var_name} as ... "
    type -P "${prog_name}" || die "failed to find '${var_name}=${prog_name}'."
}

# defaults, can be ovverided as:
#    ebuild_prog=~/bin/e $0 <args>
: ${cabal_prog:=cabal}
: ${hackport_prog:=hackport}
: ${ebuild_prog:=ebuild}
: ${pkgdev_prog:=pkgdev}

get_latest() {
    local pn=$1
    local r=
    while read p; do
        # pkg ver
        set -- ${p}
        [[ ${1,,} == ${pn} ]] && r=${2}
    done < <($cabal_prog list "${pn}" --simple-output)
    [[ -n ${r} ]] || die "failed to find latest version for '${pn}'"
    echo "${r}"
}

pn=$(basename $(pwd))
c=$(basename $(dirname $(pwd)))
ebuild_needs_regeneration=yes
autoversion=

# options parser
while :; do
    case "$1" in
        -v | --verbose  ) verbose=1; shift ;;
        -h | --help     ) usage ;;
        -c | --continue ) ebuild_needs_regeneration=no; shift ;;
        -a | --auto     ) autoversion=yes; shift ;;
        --              ) shift; break ;;
        *               ) break ;;
    esac
done

find_prog cabal_prog
find_prog hackport_prog
find_prog ebuild_prog
find_prog pkgdev_prog

if [[ ${autoversion} = yes ]]
  then
    pv=$(get_latest "${pn}")
  else
    pv=$1; shift
fi

[[ -z ${pv} ]] && usage

current_e=${pn}-${pv}.ebuild
if [[ ( ${ebuild_needs_regeneration} = yes ) || ( ! -f ${current_e} ) ]]
  then
    run $hackport_prog merge "$pn"
  else
    echo "Skip '${current_e}' regeneration. Using existing version."
fi

FEATURES="strict stricter test ${FEATURES}" \
run $ebuild_prog "${current_e}" clean install

for rmpv in "$@"; do
    [[ ${rmpv} = ${current_e} ]] || run rm "${rmpv}"
done

c=$(basename "$(dirname "$(pwd)")")

run git add --all .
run $pkgdev_prog commit --signoff -m "${c}/${pn}: bump up to ${pv}"
run git show -C -M -D
echo "Cleaning in the background"
run $ebuild_prog "${current_e}" clean >/dev/null 2>&1 &