#!/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.5.21,<1.0'

    if [ -n "$reqs" ] ; then
      pip install -r $reqs
      # FIXME: pip requires doesn't include MySQL-python
      pip install MySQL-python
    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.openstack.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"
