#!/bin/sh
set -f
error() { echo "$@" 1>&2; }
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
apt_get() {
    local ret=""
    if [ "$1" != "update" ] && ! $_APT_UPDATED; then
        error "updating apt"
        apt_get update >/dev/null || {
            ret=$?;
            error "failed to update apt [$ret]";
            return $ret;
        }
        _APT_UPDATED=true
    fi
    sudo DEBIAN_FRONTEND=noninteractive apt-get --quiet \
        --assume-yes "$@" </dev/null
}

filter_installed_packages() {
    # write to stdout, a list of packages not installed locally
    local fmt='${Package} ${Version}\n'
    LC_ALL=C dpkg-query --show "--showformat=${fmt}" "$@" 2>&1 | awk '
        $0 ~ /[Nn]o packages/ {
            sub("[.]$","",$NF);
            pkgs[n]=$NF;
            n=n+1;
        }
        $2 == "" {
                pkgs[n]=$1;
                n=n+1;
        };
        END { for(p in pkgs) {printf("%s ",pkgs[p])}; printf("\n"); }' n=0
}

apt_install() {
    local dry=$1
    shift
    needed=$(filter_installed_packages "$@")
    if [ -z "$needed" ]; then
        error "no missing depends in $*"
        return 0
    fi
    $dry_run && echo "need $needed" && return 0
    error "installing: $needed"
    apt_get install "$@"
}

get_depends() {
    # parse a debian/control for Build-Depends
    local control="$1" bdprocess="0" deps="" oifs="$IFS"
    local tab="	"
    while read line; do
        line=${line%%#*} # drop comments
        if [ "$bdprocess" = "0" ]; then
            case "$line" in
                Build-Depends:*)
                    bdprocess=1;
                    line=${line#*:};;
                *) continue;;
            esac
        fi
        case "$line" in
            \ *|"$tab"*) :;;
            [A-Z]*:*) bdprocess=0; continue;;
        esac
        IFS=","
        for tok in $line; do
            # each tok should be: package[ version-info]
            deps="${deps} ${tok%% *}"
        done
        IFS="$oifs"
    done < "$control"
    IFS="$oifs"
    _RET=$(echo ${deps})
}

dry_run=false
if [ "$1" = "--dry-run" ]; then
    dry_run=true
    shift
fi

if [ "$1" = "build" ]; then
    shift
    control=${1}
    if [ -z "$control" ]; then
        control=$(cd "${0%/*}/.." && echo $PWD/debian/control)
    fi
    [ -f "$control" ] ||
        fail "could not find debian/control"

    get_depends "$control" || fail "failed to read $control"
    deps=${_RET}
elif [ "$1" = "tox" ]; then
    shift
    deps="gnupg tox"
    # these come as needed to build python-netaddr which is
    # a pip dependency of some of the openstack packages.
    deps="$deps python-dev python3-dev build-essential" 
else
    error "expect first argument to be 'tox' or 'build'"
    exit 1
fi

apt_install $dry_run $deps
