#!/usr/bin/bash
#
# lpf Local Package Building Service wrapper script
#

scriptdir=$( dirname $(readlink -fn $0))
source $scriptdir/lpf-defs.bash


function usage()
{
    cat << EOF
Usage: lpf [-n] <command> [args]

commands:
    list        List all installed lpf packages.
    update [package]
                Interactive approve, build and install of given package or
                all packages.
    state [package]
                List package state or state of all packages.
    scan [package]
                Triage a given package or all packages  and
                update their status.
    approve <package>
                Approve a package in state approve-wait.
    build [package]
                Build given package or all packages in state
                build-wait
    rebuild <package>
                Force re-install of a package where previous installation
                failed.
    install <package>
                Install rpms for given package.
    reset <package>
                Remove all temporary files for package, set state as after
                fresh install.
    log [package]
                Display logs from last build for package, or just
                last build.
    mute <package>
                Mute (i. e., disable) notification messages for  package.
    unmute <package>
                Re-enable notification messages for a possibly muted package.
    notify [message]
                Print given message or a default  one if there are lpf
                packages in need of action - typically in need to be updated.
    spec <package>
                Copy spec file for package to current directory.
    srpm <package>
                Build a srpm file for package in current directory.
    scan-removal <package>
                Triage package with the assumption that existing target
                package is removed (use in spec scriptlets).
    version version
                Print version data.


Use the -n flag or unset \$DISPLAY to disable GUI dialogs. See the manpage for
more commands and other info.
EOF
}

function version()
# print verson data on stdout
{
    source $scriptdir/../version
    echo "Version:    $VERSION"
    echo "Commit:     $COMMIT"
    echo "Build date: $DATE"
}


function check_pkg_arg()
# check_pkg_arg <pkg>: Check a mandatory package arg, exit on errors.
{
    if [ -z "$1" ]; then
        usage
        exit 1
    fi
    if [ ! -e "$PKG_DATA_DIR/$1" ]; then
        echo "No such package: \"$1\""
        exit 2
    fi
}


function list_packages()
# Return list of installed lpf packages.
{
    if [ -n "$1" ]; then
       usage
       exit 1
    else
       for pkgdir in $(get_pkgdirs); do
           echo ${pkgdir##*/}
       done
    fi
}


function list_states_cmd()
# list_states_cmd [pkg]: print state for given package, or all.
{
    [ -n "$1" ] && check_pkg_arg "$@"
    list_states "$@"
}


function build_packages_cmd()
# build_packages_cmd [pkg]: build given package, or all.
{
    [ -n "$1" ] && check_pkg_arg "$@"
    $scriptdir/lpf-build "$@"
}


function rebuild_package()
# rebuild_package <pkg>: rebuild given packagel.
{
    check_pkg_arg "$@"
    local pkg=$1

    case $( get_state $pkg ) in
        'failed')  $scriptdir/lpf-pkgbuild 'set-state' $pkg 'build-wait'
                   $scriptdir/lpf-pkgbuild 'build' $pkg
                   ;;
        'not-approved')
                  $scriptdir/lpf-pkgbuild 'set-state' $pkg 'approve-wait'
                  lpf-approve $pkg && $scriptdir/lpf-pkgbuild 'build' $pkg
                  ;;
        *)        error "Rebuild error" "Illegal state (aborting)" >&2
                  ;;
    esac
}


function scan_packages_cmd()
# scan_packages [pkg]: triage given package, or all.
{
    [ -n "$1" ] && check_pkg_arg "$@"
    $scriptdir/lpf-pkgbuild 'scan' "$@"
}


function scan_removal_cmd()
# scan_removal <pkg>: triage given package assuming target is removed.
{
    check_pkg_arg "$@"
    $scriptdir/lpf-pkgbuild 'set-state' $1 'removing'
    scan_packages_cmd "$1"
}


function approve_package_cmd()
#approve_package_cmd <pkg>: let user approve given package.
{
    check_pkg_arg "$@"
    approve_package "$@"
}


function install_rpms_cmd()
# install_rpms_cmd <pkg>: install all rpms for given package.
{
    check_pkg_arg "$@"
    $scriptdir/lpf-install "$@"
}


function reset_cmd()
# reset_cmd <pkg>: remove all temporary files for given package. rescan.
{
    check_pkg_arg "$@"
    $scriptdir/lpf-pkgbuild 'reset' "$1"
    $scriptdir/lpf-pkgbuild 'scan' "$@"
}


function get_spec_cmd()
# get_spec_cmd <pkg>: Retrieve target spec for package to current dir.
{
    check_pkg_arg "$@"
    cp -a $LPF_DATA/packages/$1/*.spec .
    echo $(basename  $LPF_DATA/packages/$1/*.spec)
}


function hide_cmd()
# hide_cmd <pkg>: Mute given package.
{
    check_pkg_arg "$@"
    $scriptdir/lpf-notify 'hide' "$@"
}


function unhide_cmd()
# unhide_cmd <pkg>: Unmute given package.
{
    check_pkg_arg "$@"
    $scriptdir/lpf-notify 'unhide' "$@"
}


function get_srpm_cmd()
# get_srpm_cmd <pkg>: Retrieve target srpm for package to current dir.
{
    check_pkg_arg "$@"
    sources=$(rpm --eval %_sourcedir)
    cp $LPF_DATA/packages/$1/SOURCES/* $sources 2>/dev/null || :
    spectool -g -C $sources  $LPF_DATA/packages/$1/*.spec
    rpmbuild -bs  --define="_srcrpmdir $PWD" $LPF_DATA/packages/$1/*.spec
}


function update_packages()
# update_packages [pkg]: Update given package, or all packages.
{
    [ -n "$1" ] && check_pkg_arg "$@"
    $scriptdir/lpf-update "$@"
}


if [ -z "$1" -o "$1" = '-h' ]; then
    usage
    exit 1
fi

export SUDO_ASKPASS=$scriptdir/sudo_askpass
id -Gn | grep -q $LPF_GROUP  || {
    if [ "$EUID" != "0" ]; then
       $scriptdir/lpf-add-group
       exit 1
    fi
}

if [ "$( id -gn )" !=  "$LPF_GROUP" ]; then
    exec sg pkg-build "$0 $*"
fi

umask 002
trap "do_trap 81" SIGINT ERR

# http://forums.gentoo.org/viewtopic-t-947211-start-0.html
export NO_AT_BRIDGE=0

export SUDO_ASKPASS=$scriptdir/sudo_askpass

# parse basic flags with getopts
while getopts "hn" opt; do
  # shellcheck disable=2220
  case $opt in
    h) usage; exit;;
    n) unset DISPLAY;;
  esac
done
shift "$((OPTIND-1))"

# now fall through to command parsing
command=$1
shift
case $command in
    set-state)
            $scriptdir/lpf-pkgbuild 'set-state' $1 $2
            ;;
    list)   list_packages "$@"
            ;;
    state)  list_states_cmd "$@"
            ;;
    build)  build_packages_cmd "$@"
            do_trap 0
            ;;
    rebuild)
            rebuild_package "$@"
            do_trap 0
            ;;
    scan)   scan_packages_cmd "$@"
            ;;
    approve)
            $scriptdir/lpf-approve  "$@"
            do_trap 0
            ;;
    update) update_packages "$@"
            ;;
    install)
            install_rpms_cmd "$@"
            do_trap 0
            ;;
    reset)  reset_cmd "$@"
            ;;
    log)    show_buildlog "$@"
            do_trap 0
            ;;
    spec)   get_spec_cmd "$@"
            ;;
    srpm)   get_srpm_cmd "$@"
            ;;
    mute)   hide_cmd "$@"
            ;;
    unmute) unhide_cmd "$@"
            ;;
    notify) $scriptdir/lpf-notify 'cli-notify' "$@"
            ;;
    scan-removal)
            scan_removal_cmd "$@"
            ;;
    version)
            version
            ;;
    *)      usage
            exit 1
esac


# vim: set expandtab ts=4 sw=4:
