#!/usr/bin/env bash

function error_handler() {
  >&2 echo "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}."
  exit "$2"
}
trap 'error_handler ${LINENO} $?' ERR
set -o errtrace -o errexit -o nounset -o pipefail

export FLASK_SESSION_SECRET_KEY="this_is_recreate_db_secret_key"

if [[ -z "${SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR:-}" ]]; then
  script_dir="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"

  SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR="${script_dir}/../../../sample-process-models"
  if [[ ! -d "$SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR" ]]; then
    SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR="${script_dir}/../../sample-process-models"
    if [[ ! -d "$SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR" ]]; then
      >&2 echo "ERROR: Could not find a location for the sample processes. Last tried: $SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR"
      exit 1
    fi
  fi
  export SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR
fi

database_host="localhost"
if [[ -n "${SPIFFWORKFLOW_BACKEND_DATABASE_URI:-}" ]]; then
  database_host=$(grep -oP "^[^:]+://.*@\K(.+?)[:/]" <<<"$SPIFFWORKFLOW_BACKEND_DATABASE_URI" | sed -E 's/[:\/]$//')
fi

# uncomment this line to fix branching conflicts
# poetry run flask db merge heads -m "merging heads"

tasks=""
if [[ "${1:-}" == "clean" ]]; then
  subcommand="${2:-}"
  if [[ "$subcommand" == "rmall" ]]; then
    tasks="$tasks init migrate"
    rm -rf migrations/
  elif [[ -n "$subcommand" ]]; then
    >&2 echo "ERROR: you passed a subcommand that was not rmall, and that is not supported: $subcommand"
    exit 1
  fi

  if [[ "${SPIFFWORKFLOW_BACKEND_DATABASE_TYPE:-mysql}" != "mysql" ]]; then
    rm -f ./src/instance/*.sqlite3
  else
    mysql -h "$database_host" -uroot -e "DROP DATABASE IF EXISTS spiffworkflow_backend_local_development"
    mysql -h "$database_host" -uroot -e "DROP DATABASE IF EXISTS spiffworkflow_backend_unit_testing"
  fi

  # TODO: check to see if the db already exists and we can connect to it. also actually clean it up.
  # start postgres in background with one db
  if [[ "${SPIFFWORKFLOW_BACKEND_DATABASE_TYPE:-}" == "postgres" ]]; then
    container_name="postgres-spiff"
    container_regex="^postgres-spiff$"
    if [[ -n "$(docker ps -qa -f name=$container_regex)" ]]; then
      echo ":: Found postgres container - $container_name"
      if [[ -n "$(docker ps -q -f name=$container_regex)" ]]; then
        echo ":: Stopping running container - $container_name"
        docker stop $container_name
      fi
      echo ":: Removing stopped container - $container_name"
      docker rm $container_name
    fi
    if ! docker exec -it postgres-spiff psql -U spiffworkflow_backend spiffworkflow_backend_unit_testing -c "select 1"; then
      docker run --name postgres-spiff -p 5432:5432 -e POSTGRES_PASSWORD=spiffworkflow_backend -e POSTGRES_USER=spiffworkflow_backend -e POSTGRES_DB=spiffworkflow_backend_unit_testing -d postgres
      sleep 4 # classy
    fi
    if ! docker exec -it postgres-spiff psql -U spiffworkflow_backend spiffworkflow_backend_local_development -c "select 1"; then
      # create other db. spiffworkflow_backend_unit_testing came with the docker run.
      docker exec -it postgres-spiff psql -U spiffworkflow_backend spiffworkflow_backend_unit_testing -c "create database spiffworkflow_backend_local_development;"
    fi
  fi
  tasks="$tasks upgrade"
elif [[ "${1:-}" == "migrate" ]]; then
  tasks="$tasks migrate upgrade"
elif [[ "${1:-}" == "downgrade" ]]; then
  tasks="$tasks downgrade"
else
  tasks="$tasks upgrade"
fi

if [[ "${SPIFFWORKFLOW_BACKEND_DATABASE_TYPE:-mysql}" == "mysql" ]]; then
  mysql -h "$database_host" -uroot -e "CREATE DATABASE IF NOT EXISTS spiffworkflow_backend_local_development"
  mysql -h "$database_host" -uroot -e "CREATE DATABASE IF NOT EXISTS spiffworkflow_backend_unit_testing"
fi

for task in $tasks; do
  SPIFFWORKFLOW_BACKEND_ENV=local_development FLASK_APP=src/spiffworkflow_backend poetry run flask db "$task"
done

SPIFFWORKFLOW_BACKEND_ENV=unit_testing FLASK_APP=src/spiffworkflow_backend poetry run flask db upgrade
if [[ -n "${SPIFFWORKFLOW_BACKEND_ENV:-}" ]] && ! grep -Eq '^(local_development|unit_testing)$' <<< "$SPIFFWORKFLOW_BACKEND_ENV"; then
  if [[ "${SPIFFWORKFLOW_BACKEND_DATABASE_TYPE:-mysql}" == "mysql" ]]; then
    mysql -h "$database_host" -uroot -e "CREATE DATABASE IF NOT EXISTS spiffworkflow_backend_$SPIFFWORKFLOW_BACKEND_ENV"
  fi
  FLASK_APP=src/spiffworkflow_backend poetry run flask db upgrade
fi

# for ./bin/tests-par (parallel tests with xdist)
if [[ -f "./src/instance/db_unit_testing.sqlite3" ]] ; then
  for i in $(seq 0 16); do
    cp ./src/instance/db_unit_testing.sqlite3 ./src/instance/db_unit_testing_gw$i.sqlite3
  done
fi