#!/usr/bin/env bash
set -e
#set -x

NC_VERSION=${NC_VERSION:-18}
LOCAL_IMAGE=xaicorp/nextcloud
TAG=${NC_VERSION}.0-${BUILD_NUMBER:-dev}
REMOTE_IMAGE=dkregistry.xai-corp.net:5000/${LOCAL_IMAGE}:${TAG}
STACK_NAME=xaibox
SERVICE_NAME=app
APP_NAME=${STACK_NAME}_${SERVICE_NAME}

LOG=$(mktemp)

export LOCAL_IMAGE
export REMOTE_IMAGE
export TAG

export DOCKER_HOST=${DOCKER_HOST:-'dkhost:2376'}

###
function deploy() {
  docker pull "$REMOTE_IMAGE"

  docker stack deploy \
    --with-registry-auth \
    -c docker-compose.prod.yml \
    ${STACK_NAME}

  sleep 2
  docker stack ps ${STACK_NAME}

  wait_for_completed

  occ upgrade
  occ app:update --all
  occ db:add-missing-indices
#  occ db:convert-filecache-bigint
}

wait_for_completed() {
  #states supported: "rollback_completed", "updating", "completed"
  state=$(docker service inspect ${APP_NAME} | jq -r .[0].UpdateStatus.State)
  while [ "completed" != "$state" ]; do
    echo "$state"
    sleep 3
    state=$(docker service inspect ${APP_NAME} | jq -r .[0].UpdateStatus.State)
  done
  sleep 5
}

function deploy_test() {
  docker ps | grep ${APP_NAME}

  assertOK https xaibox.xai-corp.net

  assertNetwork prod_ui
  assertNetwork prod_app
  assertNetwork prod_db
  assertNetwork prod_cache

  occ check
  occ status
}

function deploy_save() {
  #tag as latest
  echo -e "\033[94mTagging image as latest\033[39m"
  docker tag "$REMOTE_IMAGE" "${REMOTE_IMAGE//${TAG}/latest}"
  docker push "${REMOTE_IMAGE//${TAG}/latest}"
}

dc() {
  # shellcheck disable=SC2068
  docker-compose \
    -f docker-compose.yml \
    -f docker-compose.prod.yml \
    $@
}

occ() {
  container=$(docker ps -qn1)
  # shellcheck disable=SC2068
  docker exec -t -u www-data "$container" php occ $@
}

function assertOK() {
  proto=$1
  domain=$2
  set -e
  echo -e "\033[94m${proto}://${domain}\033[39m"
  curl -IskH "Host: ${domain}" "${proto}://dkhost.xai-corp.net" |
    tee "$LOG" | grep -P "200 OK|302 Found|403 Forbidden"
}

function assertNetwork() {
  network=$1
  echo -e "\033[94minspecting network\033[39m $network"
  docker network inspect "$network" | jq -r .[].Containers[].Name | tee "$LOG" | grep ${APP_NAME}
}

function trap_exit() {
  code=$?
  docker service ls | grep "${APP_NAME}"
  if [ $code -gt 0 ]; then
    echo
    cat "$LOG"
    rm "$LOG"
    echo -e "\033[31mFailed to deploy ${REMOTE_IMAGE} \033[39m"
    exit $code
  fi

  rm "$LOG"
  echo -e "\033[32mSuccess:\033[39m ${REMOTE_IMAGE} successfully deployed"
}
trap trap_exit EXIT

print_usage() {
  printf "Usage: %s: [-b] [-t] [-s] \n" "$0"
  echo -d deploy
  echo -t smoke tests
  echo -s tag as latest
  echo -h help
  exit 0
}

######
if [ -z "$1" ]; then
  deploy && deploy_test && deploy_save
  exit
fi

while getopts tdhs name; do
  case $name in
  d) deploy ;;
  t) deploy_test ;;
  s) deploy_save ;;
  *) print_usage ;;
  esac
done
