#!/usr/bin/env bash

set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x

# shellcheck disable=SC1090
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"

dokku-ansible-deploy-validate-dependencies() {
  # shellcheck disable=SC2034
  declare desc="check that plugin dependencies are available"

  declare ANSIBLE_DIR="$DOKKU_ROOT/.ansible/"

  if ! command -v "ansible-playbook" &>/dev/null; then
    dokku_col_log_info1_quiet "Missing ansible dependency, run dokku plugin:install-dependencies"
    exit 1
  fi

  if [[ ! -d $ANSIBLE_DIR ]]; then
    dokku_col_log_info1_quiet "Missing $ANSIBLE_DIR, run dokku plugin:install-dependencies"
    exit 0
  fi
}

dokku-ansible-deploy-deploy-d-create() {
  # shellcheck disable=SC2034
  declare desc="create a system level deploy.d directory"

  if [[ ! -d "$DOKKU_LIB_ROOT/data/deploy.d" ]]; then
    dokku_col_log_info1_quiet "Creating $DOKKU_LIB_ROOT/data/deploy.d"
    mkdir -p "$DOKKU_LIB_ROOT/data/deploy.d"
  fi
}

dokku-ansible-deploy-vault-pass-cmd() {
  # shellcheck disable=SC2034
  declare desc="add new app vault password for decryption of passwords"

  declare APP="$2"
  declare VAULT_FILE="$DOKKU_LIB_ROOT/data/deploy.d/$APP/.vault.sh"

  if [[ ! -n "$APP" ]]; then
    dokku_col_log_info1_quiet "missing app name, try 'dokku ansible-deploy:vault-pass myappname'"
    exit 1
  fi

  if [[ -f $VAULT_FILE ]]; then
    dokku_col_log_info1_quiet "Vault password already setup for $APP"
    exit 0
  fi

  # shellcheck disable=SC2162 disable=SC2116 disable=SC2006
  read -sp "Please enter your vault password for $APP: `echo $'\n> '`" VAULT_PASSWD; echo

  if [[ ! -d "$DOKKU_LIB_ROOT/data/deploy.d/$APP" ]]; then
    dokku_col_log_info1_quiet "Creating $DOKKU_LIB_ROOT/data/deploy.d/$APP"
    mkdir -p "$DOKKU_LIB_ROOT/data/deploy.d/$APP"
  fi

  { echo "#!/bin/bash";
    echo "";
    echo "set -eu -o pipefail";
    echo "";
    echo "echo \"$VAULT_PASSWD\""; } > "$VAULT_FILE"

  chmod +x "$VAULT_FILE"

  dokku_col_log_info1_quiet "Generated $VAULT_FILE for $APP"
}

dokku-ansible-deploy-sudo-pass-cmd() {
  # shellcheck disable=SC2034
  declare desc="add new dokku user sudo password for sudo escalation"

  dokku-ansible-deploy-deploy-d-create

  declare VARS_FILE="$DOKKU_LIB_ROOT/data/deploy.d/vars.yml"

  # shellcheck disable=SC2162 disable=SC2116 disable=SC2006
  read -sp "Please enter your Dokku system user sudo password: `echo $'\n> '`" SUDO_PASSWD; echo

  { echo "---";
    echo "ansible_become_password: \"$SUDO_PASSWD\""; } > "$VARS_FILE"

  dokku_col_log_info1_quiet "Generated $VARS_FILE"
}

dokku-ansible-deploy-dependencies() {
  # shellcheck disable=SC2034
  declare desc="install plugin dependencies"

  declare DEPENDENCIES="ansible"
  declare REQUIREMENTS="$PLUGIN_AVAILABLE_PATH/ansible-deploy/deps/requirements.yml"

  dokku_col_log_info1_quiet "Ensuring the following packages are installed: $DEPENDENCIES"

  export DEBIAN_FRONTEND=noninteractive

  # shellcheck disable=SC2086
  apt update && apt install -y $DEPENDENCIES

  dokku_col_log_info1_quiet "Installing Ansible requirements"
  ansible-galaxy install --role-file "$REQUIREMENTS" --force

  dokku_col_log_info1_quiet "Copying Ansible library modules into place"

  # shellcheck disable=SC2086
  mkdir -p $DOKKU_ROOT/.ansible/{roles,plugins/modules}

  # shellcheck disable=SC2086
  cp -R $DOKKU_ROOT/.ansible/roles/*/library/* $DOKKU_ROOT/.ansible/plugins/modules
}

dokku-ansible-deploy-post-extract() {
  # shellcheck disable=SC2034
  declare desc="run the post-extract hook to setup the plugin"

  dokku-ansible-deploy-validate-dependencies

  declare APP="$1" TMPDIR="$2"

  if [[ -d "$TMPDIR/deploy.d" ]] && [[ "$(ls -A "$TMPDIR/deploy.d")" ]]; then
    mkdir -p "$DOKKU_LIB_ROOT/data/deploy.d/$APP"
    cp -R "$TMPDIR/deploy.d/." "$DOKKU_LIB_ROOT/data/deploy.d/$APP"
    dokku_col_log_info1_quiet "Copied deploy.d files and directories into place"

    if [[ -d "$TMPDIR/deploy.d/vault" ]]; then
      if [[ ! -f "$DOKKU_LIB_ROOT/data/deploy.d/$APP/.vault.sh" ]]; then
        dokku_col_log_info1_quiet "Vault directory discovered but missing vault password"
        dokku_col_log_info1_quiet "Please run dokku ansible-deploy:vault-password $APP"
        exit 1
      fi
    fi

    dokku_col_log_info1_quiet "Copying ansibile.cfg into place"
    cp -R "$PLUGIN_AVAILABLE_PATH/ansible-deploy/ansible.cfg" /home/dokku/.ansible.cfg
  fi
}

dokku-ansible-deploy-pre-deploy() {
  # shellcheck disable=SC2034
  declare desc="run the pre-deploy hook to setup an app"

  dokku-ansible-deploy-validate-dependencies

  declare APP="$1"
  declare APP_DIR="$DOKKU_LIB_ROOT/data/deploy.d/$APP"
  declare PLUGIN_DIR="$DOKKU_LIB_ROOT/data/deploy.d"
  declare VAULT_FILE="$APP_DIR/.vault.sh"
  declare PRE_DEPLOY="$PLUGIN_AVAILABLE_PATH/ansible-deploy/plays/predeploy/predeploy.yml"

  dokku_col_log_info1_quiet "Running pre-deploy steps"

  # shellcheck disable=SC2155
  local CMD_ARGS="--inventory $(hostname), --connection local"

  if [[ -f $VAULT_FILE ]]; then
    dokku_col_log_info1_quiet "$APP vault password file $VAULT_FILE discovered"
    CMD_ARGS="${CMD_ARGS} --vault-password-file $VAULT_FILE"
  fi

  dokku_col_log_info1_quiet "Running $PRE_DEPLOY"

  # shellcheck disable=SC2086
  ansible-playbook \
    --extra-vars "app=$APP" \
    --extra-vars "dokku_lib_root=$DOKKU_LIB_ROOT" \
    --extra-vars "app_config_root=$APP_DIR" \
    --extra-vars "plugin_config_root=$PLUGIN_DIR" \
    $CMD_ARGS \
    $PRE_DEPLOY
}

dokku-ansible-deploy-post-deploy() {
  # shellcheck disable=SC2034
  declare desc="run the post-deploy hook to finish an app setup"

  dokku-ansible-deploy-validate-dependencies

  declare APP="$1"
  declare APP_DIR="$DOKKU_LIB_ROOT/data/deploy.d/$APP"
  declare PLUGIN_DIR="$DOKKU_LIB_ROOT/data/deploy.d"
  declare VAULT_FILE="$APP_DIR/.vault.sh"
  declare POST_DEPLOY="$PLUGIN_AVAILABLE_PATH/ansible-deploy/plays/postdeploy/postdeploy.yml"

  dokku_col_log_info1_quiet "Running post-deploy steps"

  # shellcheck disable=SC2155
  local CMD_ARGS="--inventory $(hostname), --connection local"

  if [[ -f $VAULT_FILE ]]; then
    dokku_col_log_info1_quiet "$APP vault password file $VAULT_FILE discovered"
    CMD_ARGS="${CMD_ARGS} --vault-password-file $VAULT_FILE"
  fi

  dokku_col_log_info1_quiet "Running $POST_DEPLOY"

  # shellcheck disable=SC2086
  ansible-playbook \
    --extra-vars "app=$APP" \
    --extra-vars "dokku_lib_root=$DOKKU_LIB_ROOT" \
    --extra-vars "app_config_root=$APP_DIR" \
    --extra-vars "plugin_config_root=$PLUGIN_DIR" \
    $CMD_ARGS \
    $POST_DEPLOY
}

dokku-ansible-deploy-post-delete() {
  # shellcheck disable=SC2034
  declare desc="run the post-delete hook to remove an app"

  dokku-ansible-deploy-validate-dependencies

  declare APP="$1"
  declare APP_DIR="$DOKKU_LIB_ROOT/data/deploy.d/$APP"
  declare PLUGIN_DIR="$DOKKU_LIB_ROOT/data/deploy.d"
  declare VAULT_FILE="$APP_DIR/.vault.sh"
  declare POST_DELETE="$PLUGIN_AVAILABLE_PATH/ansible-deploy/plays/postdelete/postdelete.yml"

  dokku_col_log_info1_quiet "Running post-delete steps"

  # shellcheck disable=SC2155
  local CMD_ARGS="--inventory $(hostname), --connection local"

  if [[ -f $VAULT_FILE ]]; then
    dokku_col_log_info1_quiet "$APP vault password file $VAULT_FILE discovered"
    CMD_ARGS="${CMD_ARGS} --vault-password-file $VAULT_FILE"
  fi

  dokku_col_log_info1_quiet "Running $POST_DELETE"

  # shellcheck disable=SC2086
  ansible-playbook \
    --extra-vars "app=$APP" \
    --extra-vars "dokku_lib_root=$DOKKU_LIB_ROOT" \
    --extra-vars "app_config_root=$APP_DIR" \
    --extra-vars "plugin_config_root=$PLUGIN_DIR" \
    $CMD_ARGS \
    $POST_DELETE
}