#!/usr/bin/env bash

function gitops_mas_provisioner_help() {
  [[ -n "$1" ]] && echo_warning "$1"
  reset_colors
  cat << EOM
Usage:
  mas gitops-mas-provisioner [options]
Where ${COLOR_YELLOW}specified${TEXT_RESET} each option may also be defined by setting the appropriate environment variable.
When no options are specified on the command line, interactive-mode will be enabled by default.

GitOps Configuration:
  -d, --dir ${COLOR_YELLOW}GITOPS_WORKING_DIR${TEXT_RESET}           Directory for GitOps repository
  -a, --account-id ${COLOR_YELLOW}ACCOUNT_ID${TEXT_RESET}            Account name that the cluster belongs to
  -r, --region ${COLOR_YELLOW}REGION${TEXT_RESET}                    Region
  -c, --cluster-id ${COLOR_YELLOW}CLUSTER_ID${TEXT_RESET}            Cluster ID

Secrets Manager:
      --secrets-path ${COLOR_YELLOW}SECRETS_PATH${TEXT_RESET}                    Secrets Manager path
      --secrets-key-seperator ${COLOR_YELLOW}SECRETS_KEY_SEPERATOR${TEXT_RESET}  Secrets Manager key seperator string

MAS PROVISIONER OPERATOR:
      --status-repo-url ${COLOR_YELLOW}STATUS_REPO_URL${TEXT_RESET}                       Git repo where the order status of the operation will be recorded
      --provisioner-domain ${COLOR_YELLOW}PROVISIONER_DOMAIN${TEXT_RESET}                 The domain to setup route and service for the MAS Provisioner
    (Optional)
      --provisioner-storage-class ${COLOR_YELLOW}PROVISIONER_STORAGE_CLASS${TEXT_RESET}           The storage class for the logs PVC. Default is ocs-storagecluster-cephfs
      --provisioner-namespace ${COLOR_YELLOW}PROVISIONER_NAMESPACE${TEXT_RESET}                   Namespace for the mas provisioner
      --account-alias ${COLOR_YELLOW}ACCOUNT_ALIAS${TEXT_RESET}                                   Enables customization for the account id to use in the status repo. Default is fetched from the order payload received
      --provisioner-version ${COLOR_YELLOW}PROVISIONER_VERSION${TEXT_RESET}                       The version tag for MAS Provisioner. Default is latest
      --enable-mtls ${COLOR_YELLOW}ENABLE_MTLS${TEXT_RESET}                                       Enables mutual tls which requires ca certs to be exchanged with the client. Default is false
      --csb-client-ca-certificate-file ${COLOR_YELLOW}CSB_CLIENT_CA_CERTIFICATE_FILE${TEXT_RESET} Location of the file containing the CA certificate from MCSP CSB. Can provide when ENABLE_MTLS is set or a client auth cert would be provided in the cluster for use in test cases.
      --service-port ${COLOR_YELLOW}SERVICE_PORT${TEXT_RESET}                                     Service port. Defaults to 7329
      --base-branch ${COLOR_YELLOW}BASE_BRANCH${TEXT_RESET}                                       The reference branch that will be cloned during processing of the order in case the master branch is not used. Default is master
      --async-poll-interval ${COLOR_YELLOW}ASYNC_POLL_INTERVAL${TEXT_RESET}                       The intervals in seconds between each poll from MCSP to check the status of the orders. Default is 600
      --async-poll-max ${COLOR_YELLOW}ASYNC_POLL_MAX${TEXT_RESET}                                 The maximum amount of time in seconds for MCSP to keep polling to check the status of an order. Default is 864000
      --enable-pd-alert ${COLOR_YELLOW}ENABLE_PD_ALERT${TEXT_RESET}                               Turn PagerDuty alerts on/off. Default is false
      --enable-ocm-alert ${COLOR_YELLOW}ENABLE_OCM_ALERT${TEXT_RESET}                             Turn On Call Manager alerts on/off. Default is false
      --recommend-cluster ${COLOR_YELLOW}RECOMMEND_CLUSTER${TEXT_RESET}                           Turn cluster recommendation which uses Instana on/off. Default is false
      --instana-url-prefix ${COLOR_YELLOW}INSTANA_URL_PREFIX${TEXT_RESET}                         The suffix "/api/infrastructure-monitoring/analyze/entities" is appended to the url prefix to make api calls to instana
      --git-root-ca-certificate-file ${COLOR_YELLOW}GIT_ROOT_CA_CERTIFICATE_FILE${TEXT_RESET}     Location of the file containing the root CA certs for private Git repos
      --mas-annotations-repo-url ${COLOR_YELLOW}MAS_ANNOTATIONS_REPO_URL${TEXT_RESET}             Git repo where the MAS annotations for hyperscaler lifecycle can be managed. Defaults to the value of STATUS_REPO_URL

Automatic GitHub Push:
  -P, --github-push ${COLOR_YELLOW}GITHUB_PUSH${TEXT_RESET}        Enable automatic push to GitHub
  -H, --github-host ${COLOR_YELLOW}GITHUB_HOST${TEXT_RESET}        GitHub Hostname for your GitOps repository
  -O, --github-org  ${COLOR_YELLOW}GITHUB_ORG${TEXT_RESET}         Github org for your GitOps repository
  -R, --github-repo ${COLOR_YELLOW}GITHUB_REPO${TEXT_RESET}        Github repo for your GitOps repository
  -B, --git-branch ${COLOR_YELLOW}GIT_BRANCH${TEXT_RESET}          Git branch to commit to of your GitOps repository
  -M, --git-commit-msg ${COLOR_YELLOW}GIT_COMMIT_MSG${TEXT_RESET}  Git commit message to use when committing to of your GitOps repository
  -S, --github-ssh  ${COLOR_YELLOW}GIT_SSH${TEXT_RESET}            Git ssh key path

Other Commands:
  -h, --help                                      Show this help message
EOM

  [[ -n "$1" ]] && exit 1 || exit 0
}

function gitops_mas_provisioner_noninteractive() {
  GITOPS_WORKING_DIR=$PWD/working-dir
  SECRETS_KEY_SEPERATOR="/"
  GIT_COMMIT_MSG="gitops-mas-provisioner commit"

  # defaults for fvtsaas
  # TODO: will need to add explicit args to pipeline when we start using this code to deploy to MCSP
  export REGION=${REGION:-${SM_AWS_REGION}}

  while [[ $# -gt 0 ]]
  do
    key="$1"
    shift
    case $key in
      # GitOps Configuration
      -d|--dir)
        export GITOPS_WORKING_DIR=$1 && shift
        ;;
      -g|--gitops-version)
        echo "${COLOR_YELLOW}WARNING: the -g|--gitops-version parameter is deprecated; it has no effect and will be removed in a future release${COLOR_RESET}"
        shift
        ;;
      -a|--account-id)
        export ACCOUNT_ID=$1 && shift
        ;;
      -r|--region)
        export REGION=$1 && shift
        ;;
      -c|--cluster-id)
        export CLUSTER_ID=$1 && shift
        ;;

      # Secrets Manager
      --secrets-path)
        export SECRETS_PATH=$1 && shift
        ;;
      --secrets-key-seperator)
        export SECRETS_KEY_SEPERATOR=$1 && shift
        ;;

      # MAS PROVISIONER OPERATOR
      --provisioner-storage-class)
        export PROVISIONER_STORAGE_CLASS=$1 && shift
        ;;
      --account-alias)
        export ACCOUNT_ALIAS=$1 && shift
        ;;
      --provisioner-namespace)
        export PROVISIONER_NAMESPACE=$1 && shift
        ;;
      --provisioner-version)
        export PROVISIONER_VERSION=$1 && shift
        ;;
      --enable-mtls)
        export ENABLE_MTLS=true
        ;;
      --csb-client-ca-certificate-file)
        export CSB_CLIENT_CA_CERTIFICATE_FILE=$1 && shift
        ;;
      --service-port)
        export SERVICE_PORT=$1 && shift
        ;;
      --status-repo-url)
        export STATUS_REPO_URL=$1 && shift
        ;;
      --provisioner-domain)
        export PROVISIONER_DOMAIN=$1 && shift
        ;;
      --base-branch)
        export BASE_BRANCH=$1 && shift
        ;;
      --async-poll-interval)
        export ASYNC_POLL_INTERVAL=$1 && shift
        ;;
      --async-poll-max)
        export ASYNC_POLL_MAX=$1 && shift
        ;;
      --enable-pd-alert)
        export ENABLE_PD_ALERT=true
        ;;
      --enable-ocm-alert)
        export ENABLE_OCM_ALERT=true
        ;;
      --recommend-cluster)
        export RECOMMEND_CLUSTER=true
        ;;
      --instana-url-prefix)
        export INSTANA_URL_PREFIX=$1 && shift
        ;;
      --git-root-ca-certificate-file)
        export GIT_ROOT_CA_CERTIFICATE_FILE=$1 && shift
        ;;
      --mas-annotations-repo-url)
        export MAS_ANNOTATIONS_REPO_URL=$1 && shift
        ;;

      # Automatic GitHub Push
      -P|--github-push)
        export GITHUB_PUSH=true
        ;;
      -H|--github-host)
        export GITHUB_HOST=$1 && shift
        ;;
      -O|--github-org)
        export GITHUB_ORG=$1 && shift
        ;;
      -R|--github-repo)
        export GITHUB_REPO=$1 && shift
        ;;
      -B|--git-branch)
        export GIT_BRANCH=$1 && shift
        ;;
      -M|--git-commit-msg)
        export GIT_COMMIT_MSG=$1 && shift
        ;;

      -S|--github-ssh)
        export GIT_SSH=$1 && shift
        ;;

      # Other Commands
      -h|--help)
        gitops_mas_provisioner_help
        ;;
      *)
        # unknown option
        echo -e "${COLOR_RED}Usage Error: Unsupported option \"${key}\"${COLOR_RESET}\n"
        gitops_mas_provisioner_help  "Usage Error: Unsupported option \"${key}\" "
        exit 1
        ;;
    esac
  done

  [[ -z "$GITOPS_WORKING_DIR" ]] && gitops_mas_provisioner_help "GITOPS_WORKING_DIR is not set"
  [[ -z "$ACCOUNT_ID" ]] && gitops_mas_provisioner_help "ACCOUNT_ID is not set"
  [[ -z "$REGION" ]] && gitops_mas_provisioner_help "REGION is not set"
  [[ -z "$CLUSTER_ID" ]] && gitops_mas_provisioner_help "CLUSTER_ID is not set"

  if [[ "$GITHUB_PUSH" == "true" ]]; then
    [[ -z "$GITHUB_HOST" ]] && gitops_mas_provisioner_help "GITHUB_HOST is not set"
    [[ -z "$GITHUB_ORG" ]] && gitops_mas_provisioner_help "GITHUB_ORG is not set"
    [[ -z "$GITHUB_REPO" ]] && gitops_mas_provisioner_help "GITHUB_REPO is not set"
    [[ -z "$GIT_BRANCH" ]] && gitops_mas_provisioner_help "GIT_BRANCH is not set"
  fi

  [[ -z "$STATUS_REPO_URL" ]] && gitops_mas_provisioner_help "STATUS_REPO_URL is not set"
  [[ -z "$PROVISIONER_DOMAIN" ]] && gitops_mas_provisioner_help "PROVISIONER_DOMAIN is not set"

}

function gitops_mas_provisioner() {
  # Take the first parameter off (it will be create-gitops)
  shift
  if [[ $# -gt 0 ]]; then
    gitops_mas_provisioner_noninteractive "$@"
  else
    echo "Not supported yet"
    exit 1
    gitops_mas_provisioner_interactive
  fi

  # catch errors
  set -o pipefail
  trap 'echo "[ERROR] Error occurred at $BASH_SOURCE, line $LINENO, exited with $?"; exit 1' ERR

  mkdir -p ${GITOPS_WORKING_DIR}
  GITOPS_CLUSTER_DIR=${GITOPS_WORKING_DIR}/${GITHUB_REPO}/${ACCOUNT_ID}/${CLUSTER_ID}

  # set default values of envs if not provided
  export PROVISIONER_STORAGE_CLASS=${PROVISIONER_STORAGE_CLASS:-"ocs-storagecluster-cephfs"}
  export ENABLE_MTLS=${ENABLE_MTLS:-false}
  export ENABLE_OCM_ALERT=${ENABLE_OCM_ALERT:-false}
  export ENABLE_PD_ALERT=${ENABLE_PD_ALERT:-false}
  export PROVISIONER_VERSION=${PROVISIONER_VERSION:-latest}
  export PROVISIONER_NAMESPACE=${PROVISIONER_NAMESPACE:-"mas-provisioner"}
  export BASE_BRANCH=${BASE_BRANCH:-master}
  export SERVICE_PORT=${SERVICE_PORT:-7329}
  export ASYNC_POLL_INTERVAL=${ASYNC_POLL_INTERVAL:-600}
  export ASYNC_POLL_MAX=${ASYNC_POLL_MAX:-864000}
  export RECOMMEND_CLUSTER=${RECOMMEND_CLUSTER:-false}
  export INSTANA_URL_PREFIX=${INSTANA_URL_PREFIX:-"https://maximonp-ibmaiapps.instana.io"}
  export MAS_ANNOTATIONS_REPO_URL=${MAS_ANNOTATIONS_REPO_URL:-$STATUS_REPO_URL}

  echo
  reset_colors
  echo_h2 "Review Settings"

  echo "${TEXT_DIM}"
  echo_h2 "Target" "    "
  echo_reset_dim "Account ID ............................ ${COLOR_MAGENTA}${ACCOUNT_ID}"
  echo_reset_dim "Region ................................ ${COLOR_MAGENTA}${REGION}"
  echo_reset_dim "Cluster ID ............................ ${COLOR_MAGENTA}${CLUSTER_ID}"
  echo_reset_dim "Cluster Config Directory .............. ${COLOR_MAGENTA}${GITOPS_CLUSTER_DIR}"
  reset_colors

  echo "${TEXT_DIM}"
  echo_h2 "Secrets Manager" "    "
  echo_reset_dim "Secrets Path .......................... ${COLOR_MAGENTA}${SECRETS_PATH}"
  reset_colors

  echo "${TEXT_DIM}"
  if [[ "$GITHUB_PUSH" == "true" ]]; then
    echo_h2 "GitOps Target" "    "
    echo_reset_dim "Automatic Push ........................ ${COLOR_GREEN}Enabled"
    echo_reset_dim "Working Directory ..................... ${COLOR_MAGENTA}${GITOPS_WORKING_DIR}"
    echo_reset_dim "Host .................................. ${COLOR_MAGENTA}${GITHUB_HOST}"
    echo_reset_dim "Organization .......................... ${COLOR_MAGENTA}${GITHUB_ORG}"
    echo_reset_dim "Repository ............................ ${COLOR_MAGENTA}${GITHUB_REPO}"
    echo_reset_dim "Branch ................................ ${COLOR_MAGENTA}${GIT_BRANCH}"
  else
    echo_h2 "GitOps Target" "    "
    echo_reset_dim "Automatic Push ........................ ${COLOR_RED}Disabled"
    echo_reset_dim "Working Directory ..................... ${COLOR_MAGENTA}${GITOPS_WORKING_DIR}"
  fi
  reset_colors


  echo "${TEXT_DIM}"
  echo_h2 "MAS Provisioner" "    "
  echo_reset_dim "Provisioner Namespace ................... ${COLOR_MAGENTA}${PROVISIONER_NAMESPACE}"
  echo_reset_dim "Provisioner Version ..................... ${COLOR_MAGENTA}${PROVISIONER_VERSION}"
  echo_reset_dim "Provisioner Domain ...................... ${COLOR_MAGENTA}${PROVISIONER_DOMAIN}"
  echo_reset_dim "Status Repo URL ......................... ${COLOR_MAGENTA}${STATUS_REPO_URL}"
  echo_reset_dim "MAS Annotations Repo URL ................ ${COLOR_MAGENTA}${MAS_ANNOTATIONS_REPO_URL}"
  echo_reset_dim "Base Branch ............................. ${COLOR_MAGENTA}${BASE_BRANCH}"
  echo_reset_dim "Enable MTLS ............................. ${COLOR_MAGENTA}${ENABLE_MTLS}"
  echo_reset_dim "Enable PD Alert ......................... ${COLOR_MAGENTA}${ENABLE_PD_ALERT}"
  echo_reset_dim "Enable OCM Alert ........................ ${COLOR_MAGENTA}${ENABLE_OCM_ALERT}"
  echo_reset_dim "Recommend Cluster ....................... ${COLOR_MAGENTA}${RECOMMEND_CLUSTER}"
  reset_colors

  CURRENT_DIR=$PWD
  TEMP_DIR=$CURRENT_DIR/tmp-masprov
  mkdir -p $TEMP_DIR

  if [ -z $GIT_SSH ]; then
    export GIT_SSH="false"
  fi

  # Set up secrets
  # ---------------------------------------------------------------------------
  echo
  echo_h2 "Configuring MAS Provisioner Secrets"
  AVP_TYPE=aws
  sm_login

  export SECRET_NAME_IBM_ENTITLEMENT=${ACCOUNT_ID}${SECRETS_KEY_SEPERATOR}${CLUSTER_ID}${SECRETS_KEY_SEPERATOR}ibm_entitlement
  export SECRET_KEY_IBM_ENTITLEMENT=${SECRET_NAME_IBM_ENTITLEMENT}#image_pull_secret_b64
  export SECRET_NAME_GITHUB_TOKEN=${ACCOUNT_ID}${SECRETS_KEY_SEPERATOR}${CLUSTER_ID}${SECRETS_KEY_SEPERATOR}git
  export SECRET_KEY_GITHUB_TOKEN=${SECRET_NAME_GITHUB_TOKEN}#token

  echo "- Verify that IBM entitlement pull secret exists"
  sm_verify_secret_exists ${SECRET_NAME_IBM_ENTITLEMENT} "image_pull_secret_b64"

  if [ "$RECOMMEND_CLUSTER" == "true" ]; then
    if [ -n "$INSTANA_KEY" ]; then
      export SECRET_NAME_INSTANA_API=${ACCOUNT_ID}${SECRETS_KEY_SEPERATOR}${CLUSTER_ID}${SECRETS_KEY_SEPERATOR}instana
      export SECRET_KEY_INSTANA_API=${SECRET_NAME_INSTANA_API}#key
      echo "- Update INSTANA_KEY secret"
      TAGS="[{\"Key\": \"source\", \"Value\": \"gitops_cluster\"}, {\"Key\": \"account\", \"Value\": \"${ACCOUNT_ID}\"}, {\"Key\": \"cluster\", \"Value\": \"${CLUSTER_ID}\"}]"
      sm_update_secret ${SECRET_NAME_INSTANA_API} "{\"key\": \"${INSTANA_KEY}\"}" "${TAGS}"
    else
      echo_warning "'RECOMMEND_CLUSTER' has been set but 'INSTANA_KEY' was not provided"
      exit 1
    fi
  fi

  if [ -n "$GITHUB_PAT" ]; then
    echo "- Update GITHUB_PAT secret"
    TAGS="[{\"Key\": \"source\", \"Value\": \"gitops_mas_provisioner\"}, {\"Key\": \"account\", \"Value\": \"${ACCOUNT_ID}\"}, {\"Key\": \"cluster\", \"Value\": \"${CLUSTER_ID}\"}]"
    sm_update_secret ${SECRET_NAME_GITHUB_TOKEN} "{\"token\": \"${GITHUB_PAT}\"}" "${TAGS}"
  fi

  if [ "$ENABLE_PD_ALERT" == "true" ]; then
    if [ -n "$PAGERDUTY_KEY" ]; then
      export SECRET_NAME_PAGERDUTY=${ACCOUNT_ID}${SECRETS_KEY_SEPERATOR}${CLUSTER_ID}${SECRETS_KEY_SEPERATOR}pd
      export SECRET_KEY_PAGERDUTY=${SECRET_NAME_PAGERDUTY}#key
      echo "- Update PAGERDUTY_KEY secret"
      TAGS="[{\"Key\": \"source\", \"Value\": \"gitops_mas_provisioner\"}, {\"Key\": \"account\", \"Value\": \"${ACCOUNT_ID}\"}, {\"Key\": \"cluster\", \"Value\": \"${CLUSTER_ID}\"}]"
      sm_update_secret ${SECRET_NAME_PAGERDUTY} "{\"key\": \"${PAGERDUTY_KEY}\"}" "${TAGS}"
    else
      echo_warning "'ENABLE_PD_ALERT' has been set but 'PAGERDUTY_KEY' was not provided"
      exit 1
    fi
  fi

  if [ "$ENABLE_OCM_ALERT" == "true" ]; then
    if [ -n "$OCM_API_KEY" ]; then
      export SECRET_NAME_OCM_API=${ACCOUNT_ID}${SECRETS_KEY_SEPERATOR}${CLUSTER_ID}${SECRETS_KEY_SEPERATOR}ocm
      export SECRET_KEY_OCM_API=${SECRET_NAME_OCM_API}#api
      echo "- Update OCM_API_KEY secret"
      TAGS="[{\"Key\": \"source\", \"Value\": \"gitops_mas_provisioner\"}, {\"Key\": \"account\", \"Value\": \"${ACCOUNT_ID}\"}, {\"Key\": \"cluster\", \"Value\": \"${CLUSTER_ID}\"}]"
      sm_update_secret ${SECRET_NAME_OCM_API} "{\"api\": \"${OCM_API_KEY}\"}" "${TAGS}"
    else
      echo_warning "'ENABLE_OCM_ALERT' has been set but 'OCM_API_KEY' was not provided"
      exit 1
    fi
  fi

  if [ "$ENABLE_MTLS" == "true" ]; then
    if [ -s "$CSB_CLIENT_CA_CERTIFICATE_FILE" ]; then
      export CSB_CLIENT_CA_CERT=$(cat ${CSB_CLIENT_CA_CERTIFICATE_FILE} | base64 -w0)
    else
      echo "Since MTLS is enabled but 'CSB_CLIENT_CA_CERTIFICATE_FILE' is missing or empty. A client auth secret 'mas-provisioner-client-tls' will be created in the cluster for Client Auth purposes and to allow MTLS."
    fi
  fi

  if [ -s "$GIT_ROOT_CA_CERTIFICATE_FILE" ]; then
    export GIT_ROOT_CA_CERTIFICATE=$(cat ${GIT_ROOT_CA_CERTIFICATE_FILE} | base64 -w0)
  fi

  echo "- Verify that git secret exists"
  sm_verify_secret_exists ${SECRET_NAME_GITHUB_TOKEN} "token"

  # Set and Validate App Names
  # ---------------------------------------------------------------------------
  ROOT_APP_NAME="root.${ACCOUNT_ID}"
  CLUSTER_APP_NAME="cluster.${CLUSTER_ID}"
  MAS_PROVISIONER_APP_NAME="mas-provisioner.${CLUSTER_ID}"

  validate_app_name "${ROOT_APP_NAME}"
  validate_app_name "${CLUSTER_APP_NAME}"
  validate_app_name "${MAS_PROVISIONER_APP_NAME}"


  # Clone github target repo
  # ---------------------------------------------------------------------------
  if [ "$GITHUB_PUSH" == "true" ]; then
    echo
    echo_h2 "Cloning GitHub repo $GITHUB_ORG $GITHUB_REPO"
    clone_target_git_repo $GITHUB_HOST $GITHUB_ORG $GITHUB_REPO $GIT_BRANCH $GITOPS_WORKING_DIR $GIT_SSH
  fi
  mkdir -p ${GITOPS_CLUSTER_DIR}


  # Generate ArgoApps
  # ---------------------------------------------------------------------------
  echo
  echo_h2 "Generating MAS Provisioner Application"
  echo "- MAS Provisioner"

  echo "Generating MAS Provisioner file ${GITOPS_CLUSTER_DIR}/mas-provisioner.yaml"
  jinjanate_commmon $CLI_DIR/templates/gitops/appset-configs/cluster/mas-provisioner.yaml.j2 ${GITOPS_CLUSTER_DIR}/mas-provisioner.yaml

  # Commit and push to github target repo
  # ---------------------------------------------------------------------------
  if [ "$GITHUB_PUSH" == "true" ]; then
    echo
    echo_h2 "Commit and push changes to GitHub repo $GITHUB_ORG $GITHUB_REPO"
    save_to_target_git_repo $GITHUB_HOST $GITHUB_ORG $GITHUB_REPO $GIT_BRANCH "${GITOPS_WORKING_DIR}/${GITHUB_REPO}" "${GIT_COMMIT_MSG}"
    remove_git_repo_clone $GITOPS_WORKING_DIR/$GITHUB_REPO
  fi

  rm -rf $TEMP_DIR

}
