#!/bin/bash
set -eux

function python_install() {
    local svc_root=$1
    local install_dir=$2
    local system_site_packages=${3:-"False"}
    local name=$(basename $install_dir)
    local svc_manifest=$(get-pip-manifest $name)

    SITE_PCKGS="--no-site-packages"
        if [ $system_site_packages == "True" ]; then
    SITE_PCKGS="--system-site-packages"
    fi
    mkdir -p $(dirname $install_dir)
    virtualenv $SITE_PCKGS $install_dir

    set +u
    source $install_dir/bin/activate
    set -u

    # If given an exact deps list, use it, and upgrade to the local git service
    if [ -n "$svc_manifest" ]; then
        use-pip-manifest $svc_manifest
    else
        if [ -e $svc_root/requirements.txt ]; then
            reqs=$svc_root/requirements.txt
        elif [ -e $svc_root/tools/pip-requires ]; then
            reqs=$svc_root/tools/pip-requires
        else
            reqs=""
        fi

        # bug #1201253 : virtualenv-1.10.1 embeds setuptools-0.9.8, which
        # doesn't manage correctly HTTPS sockets when downloading pbr from
        # https://pypi.python.org/simple/ if using http_proxy and
        # https_proxy envvars
        pip install -U 'setuptools>=1.0'

        # bug #1293812 : Avoid easy_install triggering on pbr.
        pip install -U 'pbr>=0.11'

        if [ -n "$reqs" ] ; then
            # Install requirements off source repo if the install type
            # "source" has been specified and a cloned repo exists.
            for i in $(cat $reqs | grep -v ^# | grep -v ^$ | awk -F'[=><]' '{print $1}') ; do
                INSTALL_TYPE_VAR=DIB_INSTALLTYPE_${i//[^A-Za-z0-9]/_}
                INSTALL_TYPE=${!INSTALL_TYPE_VAR:-source}
                GIT_CLONE_DIR="/opt/stack/$i"
                if [ "$INSTALL_TYPE" = "source" ] && [ -d "$GIT_CLONE_DIR" ] ; then
                    pip install $GIT_CLONE_DIR
                fi
            done

            pip install -r $reqs
        fi
    fi
    # Always replay this, as we cannot use the entry this would generate in the manifest
    pip install $svc_root

    # Write the manifest of what was installed
    write-pip-manifest $name

    set +u
    deactivate
    set -u
}


function install_os_service() {
    local user=$1
    local repo=$(echo $2 | sed 's/github.com/review.opendev.org/')
    local branch=$3
    local directory=$4
    local system_site_packages=$5

    id $user || useradd $user --system -d /var/run/$user -s /bin/false

    install -d -m 0750 -o $user -g $user /etc/$user

    local svc_root=/opt/stack/$user
    local git_dir="--git-dir $svc_root/.git"

    # if the repository is an absolute local path then
    # we assume its present, on the correct branch and use it
    # this would be the case when the source was retrieved by
    # the source-repositories element
    if [ "${repo:0:1}" = "/" ] ; then
        python_install $repo $directory $system_site_packages
    elif [ ! -e $svc_root ]; then
        git clone --depth=1 -b $branch $repo $svc_root
        python_install $svc_root $directory $system_site_packages
    else
        if ! git $git_dir remote -v | grep $repo; then
            echo "ERROR: $svc_root exists and did not come from $repo"
            exit 1
        fi
        actual_rev=$(git $git_dir show | head -1 | awk '{print $2}')
        git $git_dir checkout $branch
        expected_rev=$(git $git_dir show | head -1 | awk '{print $2}')
        if [ "$expected_rev" != "$actual_rev" ]; then
            echo "ERROR: $repo exists and is not on rev $branch"
            exit 1
        fi
    fi
}


function usage() {
    echo "options:"
    echo "  -h   show usage and exit"
    echo "  -r   service's git repo url"
    echo "  -b   repo branch or ref (default 'master')"
    echo "  -i   Optional: installation directory for the virtualenv."
    echo "       If not specified defaults to /opt/stack/venv/<service_name>."
    echo "  -u   name of the service run-as user"
    echo "  -s   enable --system-site-packages in the virtualenv."
}

user=
repo=
install_dir=
system_site_packages="False"
while getopts hsr:u:b:i: opt; do
    case "$opt" in
    u)  user=$OPTARG;;
    i)  install_dir=$OPTARG;;
    h)  usage; exit 0;;
    r)  repo=$OPTARG;;
    b)  branch=$OPTARG;;
    s)  system_site_packages="True";;
    \?) usage; exit 1;;
    :) usage; exit 1;;
    esac
done

branch=${branch:-master}

if [[ -z "$user" || -z "$repo" ]]; then
    echo "missing required parameter"
    exit 1
fi

if [[ -z "$install_dir" ]]; then
    install_dir="/opt/stack/venvs/$user"
fi

install-packages python-dev git-core gcc libc6-dev libxml2-dev libxslt-dev libz-dev
install_os_service "$user" "$repo" "$branch" "$install_dir" "$system_site_packages"
