#!/bin/sh
set -f

error() { echo "$@" 1>&2; }
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
apt_get() {
    local ret=""
    if [ "$1" != "update" ] && ! ${_APT_UPDATED:-false}; then
        error "updating apt"
        apt_get update >/dev/null || {
            ret=$?;
            error "failed to update apt [$ret]";
            return $ret;
        }
        _APT_UPDATED=true
    fi
    local emd=""
    command -v "eatmydata" >/dev/null 2>&1 && emd="eatmydata"
    set -- sudo \
        ${http_proxy:+"http_proxy=${http_proxy}"} \
        ${https_proxy:+"https_proxy=${https_proxy}"} \
        ${no_proxy:+"no_proxy=${no_proxy}"} \
        DEBIAN_FRONTEND=noninteractive \
        $emd apt-get --quiet --assume-yes --no-install-recommends "$@"
    error "Running: $*"
    "$@" </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;
                    # let the echo trim leading space.
                    line=$(echo ${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} devscripts fakeroot build-essential"
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" 
    deps="$deps python-dev python3-dev build-essential"
    arch=$(dpkg --print-architecture)
    case "$arch" in
        i386|amd64) :;;
       *) deps="${deps} libffi-dev libssl-dev";;
    esac
else
    error "expect first argument to be 'tox' or 'build'"
    exit 1
fi

apt_install $dry_run $deps
