#!/usr/bin/env bash
# Install and setup Openshift Gitops

function gitops_bootstrap_help() {
  [[ -n "$1" ]] && echo_warning "$1"
  reset_colors
  cat << EOM
Usage:
  mas gitops-bootstrap [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.

Options:
  -a, --account-id ${COLOR_YELLOW}ACCOUNT_ID${TEXT_RESET}                Account ID
      --app-revision ${COLOR_YELLOW}APP_REVISION${TEXT_RESET}            Revision (branch or tag) of ibm-mas/gitops to use
      --argoapp-namespace ${COLOR_YELLOW}ARGOAPP_NAMESPACE${TEXT_RESET}  Namespace in the ArgoCD worker cluster to create ArgoCD Application and ApplicationSet resources (defaults to 'openshift-gitops)
      --auto-delete ${COLOR_YELLOW}AUTO_DELETE${TEXT_RESET}                  If set (or AUTO_DELETE set to exactly "true"), ArgoCD will be permitted to automatically delete resources based on config / helm chart changes. Only recommended for use in development environments.
      --cli-version ${COLOR_YELLOW}CLI_VERSION${TEXT_RESET}              CLI Version to be used to run avp container

AWS Secrets Manager Configuration:
      --sm-aws-secret-region ${COLOR_YELLOW}SM_AWS_REGION${TEXT_RESET}          Region of the AWS Secrets Manager to use
      --sm-aws-access-key ${COLOR_YELLOW}SM_AWS_ACCESS_KEY_ID${TEXT_RESET}      Your AWS Access Key ID
      --sm-aws-secret-key ${COLOR_YELLOW}SM_AWS_SECRET_ACCESS_KEY${TEXT_RESET}  Your AWS Secret Key

GitHub Repository Configuration:
      --github-url ${COLOR_YELLOW}APP_REPO_URL${TEXT_RESET}            URL to the GitHub repository holding your ArgoCD applications
      --github-revision ${COLOR_YELLOW}APP_REPO_REVISION${TEXT_RESET}  Revision (branch or tag) of your application repository to use
      --github-pat ${COLOR_YELLOW}APP_REPO_PAT${TEXT_RESET}            Personal Access Token to access your GitHub repository

Other Commands:
      --no-confirm                                Mirror images without prompting for confirmation
  -h, --help                                      Show this help message
EOM
  [[ -n "$1" ]] && exit 1 || exit 0
}

function gitops_bootstrap_noninteractive() {
  AVP_TYPE=aws

  export ARGOAPP_NAMESPACE=${ARGOAPP_NAMESPACE:-"openshift-gitops"}
  export CLI_VERSION=${CLI_VERSION:-"latest"}

  while [[ $# -gt 0 ]]
  do
    key="$1"
    shift
    case $key in
      -a|--account-id)
        export ACCOUNT_ID=$1 && shift
        ;;
      --app-revision)
        export APP_REVISION=$1 && shift
        ;;

      --argoapp-namespace)
        export ARGOAPP_NAMESPACE=$1 && shift
        ;;
      
      --auto-delete)
        export AUTO_DELETE="true"
        ;;
      --cli-version)
        export CLI_VERSION=$1 && shift
        ;;

      # AWS Secrets Manager Configuration
      --sm-aws-secret-region)
        export SM_AWS_REGION=$1 && shift
        ;;
      --sm-aws-access-key)
        export SM_AWS_ACCESS_KEY_ID=$1 && shift
        ;;
      --sm-aws-secret-key)
        export SM_AWS_SECRET_ACCESS_KEY=$1 && shift
        ;;

      # GitHub Repository Configuration
      --github-url)
        export APP_REPO_URL=$1 && shift
        ;;
      --github-revision)
        export APP_REPO_REVISION=$1 && shift
        ;;
      --github-pat)
        export APP_REPO_PAT=$1 && shift
        ;;

      # Show help
      -h|--help)
        gitops_bootstrap_help
        ;;
      # Unknown option
      *)
        gitops_bootstrap_help "Usage Error: Unsupported option \"${key}\" "
        ;;
    esac
  done

  if [ -z $SM_AWS_REGION ] || [ -z $SM_AWS_SECRET_ACCESS_KEY ] || [ -z $SM_AWS_ACCESS_KEY_ID ]; then
    echo 'Missing required params for AWS secret manager, make sure to provide --sm-aws-secret-region, --sm-aws-secret-key and --sm-aws-access-key'
    exit 1
  fi

  if [ -z $APP_REPO_URL ] || [ -z $APP_REPO_PAT ]|| [ -z $APP_REPO_REVISION ]; then
    echo 'No Environment watcher github repository provided, make sure to provide --github-pat, --github-url, and  --github-revision'
    exit 1
  fi

}


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

  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 "Applicaton Revision ............ ${COLOR_MAGENTA}${APP_REVISION}"
  echo_reset_dim "Argo Application Namespace ..... ${COLOR_MAGENTA}${ARGOAPP_NAMESPACE}"
  if [[ "${AUTO_DELETE}" == "true" ]]; then
    echo_reset_dim "Auto Delete .................... ${COLOR_GREEN}enabled"
  else
    echo_reset_dim "Auto Delete .................... ${COLOR_RED}disabled"
  fi
  echo_reset_dim "CLI Version .................... ${COLOR_MAGENTA}${CLI_VERSION}"
  reset_colors

  echo ""
  echo "${TEXT_DIM}"
  echo_h2 "AWS Secret Manager" "    "
  echo_reset_dim "Region ......................... ${COLOR_MAGENTA}${SM_AWS_REGION}"
  echo_reset_dim "Secret Key ..................... ${COLOR_MAGENTA}${SM_AWS_ACCESS_KEY_ID:0:4}<snip>"
  echo_reset_dim "Access Key ..................... ${COLOR_MAGENTA}${SM_AWS_SECRET_ACCESS_KEY:0:4}<snip>"
  reset_colors

  echo ""
  echo "${TEXT_DIM}"
  echo_h2 "GitHub Repository" "    "
  echo_reset_dim "Repository URL ................. ${COLOR_MAGENTA}${APP_REPO_URL}"
  echo_reset_dim "Repository Revision ............ ${COLOR_MAGENTA}${APP_REPO_REVISION}"
  echo_reset_dim "Personal Access Token .......... ${COLOR_MAGENTA}${APP_REPO_PAT:0:4}<snip>"
  reset_colors


  # 1. Install Openshift GitOps Operator
  echo
  echo_h2 "Install Openshift GitOps Operator"

  echo "Installing OpenShift GitOps Operator (latest) ..."

  oc apply  -f ${CLI_DIR}/templates/gitops/bootstrap/subscription.yaml

  oc get crd argocds.argoproj.io
  LOOKUP_RESULT=$?
  while [ "$LOOKUP_RESULT" == "1" ]; do
    echo "Waiting 5s for argocds.argoproj.io CRD to be installed before checking again ..."
    sleep 5
    oc get crd argocds.argoproj.io
    LOOKUP_RESULT=$?
  done

  echo "Wait for GitOps operator to be ready"
  oc wait --for=condition=Established crd/argocds.argoproj.io --timeout=30m

  oc get namespace openshift-gitops
  LOOKUP_RESULT=$?
  while [ "$LOOKUP_RESULT" == "1" ]; do
    echo "Waiting 5s for openshift-gitops namespace to be installed before checking again ..."
    sleep 5
    oc get namespace openshift-gitops
    LOOKUP_RESULT=$?
  done

  # 2. Create Secret Manager secret
  echo 'Create Secret Manager Backend Secret'
  jinjanate_commmon ${CLI_DIR}/templates/gitops/bootstrap/secret-${AVP_TYPE}.yaml.j2 | oc apply  -f -

  # 3. Create repo server SA
  echo 'Create ArgoCD repo server service account'
  oc apply  -f ${CLI_DIR}/templates/gitops/bootstrap/rbac.yaml

  # 4. Create ConfigPluginManagement
  echo 'Create Plugin configmap'
  oc apply  -f ${CLI_DIR}/templates/gitops/bootstrap/configmap.yaml

  # 5. Patch openshift-gitops with argocd-vault-plugin when it is ready
  echo 'Patch cluster ArgoCD'
  oc wait --for=jsonpath='{.status.phase}'=Available argocd/openshift-gitops -n openshift-gitops --timeout=30m
  oc wait --for=jsonpath='{.status.repo}'=Running argocd/openshift-gitops -n openshift-gitops --timeout=30m
  oc wait --for=jsonpath='{.status.applicationController}'=Running argocd/openshift-gitops -n openshift-gitops --timeout=30m
  jinjanate_commmon ${CLI_DIR}/templates/gitops/bootstrap/argocd.yaml.j2 | oc apply -f -

  sleep 30

  echo 'Wait for ArgoCd to be Ready and Functional'
  oc wait --for=jsonpath='{.status.phase}'=Available argocd/openshift-gitops -n openshift-gitops --timeout=30m
  oc wait --for=jsonpath='{.status.repo}'=Running argocd/openshift-gitops -n openshift-gitops --timeout=30m
  oc wait --for=jsonpath='{.status.applicationController}'=Running argocd/openshift-gitops -n openshift-gitops --timeout=30m

  # 6. Add the GitHub PAT secret (used to authenticate to your environment repository, which is assumed to be private)
  jinjanate_commmon ${CLI_DIR}/templates/gitops/bootstrap/secret-github.yaml.j2 | oc apply -f -

  # 7. Add the root project and application
  oc apply  -f ${CLI_DIR}/templates/gitops/bootstrap/mas-appproject.yaml
  jinjanate_commmon ${CLI_DIR}/templates/gitops/bootstrap/root-application.yaml.j2 | oc apply -f -

  # 8. Patch openshift-marketplace and kube-system to allow GitOps to manage resources in the namespace
  echo 'Patch standard namespaces to enable GitOps management'
  oc apply  -f ${CLI_DIR}/templates/gitops/bootstrap/namespace.yaml

  # 9. Add cluster-admin access to openshift-gitops service account. Need to created securitycontextcontraints
  echo 'Add cluster-admin access to openshift-gitops service account'
  oc adm policy add-cluster-role-to-user cluster-admin system:serviceaccount:openshift-gitops:openshift-gitops-argocd-application-controller

  # 10. For some reason the application-controller needs restarting to pickup the RBAC changes
  echo 'Restart application-controller'
  oc rollout restart statefulset/openshift-gitops-application-controller -n openshift-gitops

  echo 'Waiting for rollout of application-controller to complete'
  oc rollout status statefulset/openshift-gitops-application-controller -n openshift-gitops

  echo
  echo "${COLOR_GREEN}OpenShift GitOps Operator is installed and ready${COLOR_RESET}"
  echo

  # 11. Fecth Argocd Details
  if [ -z $ARGOCD_URL ] || [ -z $ARGOCD_USERNAME ] || [ -z $ARGOCD_PASSWORD ]; then
    export ARGOCD_URL=$(oc get route  openshift-gitops-server -n openshift-gitops -ojsonpath='{.spec.host}')
    export ARGOCD_USERNAME=admin
    export ARGOCD_PASSWORD=$(oc get secret openshift-gitops-cluster -n openshift-gitops -ojsonpath='{.data.admin\.password}' | base64 -d ; echo)
  fi

  # 12. Add cluster to ARgoCD
  argocd login ${ARGOCD_URL} --username ${ARGOCD_USERNAME} --password ${ARGOCD_PASSWORD} --insecure --skip-test-tls
  export K8S_AUTH_CONTEXT=$(oc whoami -c)
  argocd cluster add $K8S_AUTH_CONTEXT -y
  rc=$?
  if [[ $rc != "0" ]]; then
    echo 
    echo "argocd cluster add failed with $rc, try again"
    echo
    sleep 10
    argocd cluster add $K8S_AUTH_CONTEXT -y
  fi

  echo "${COLOR_GREEN}ArgoCD is now available at https://${ARGOCD_URL} username is: admin and password: ${ARGOCD_PASSWORD} ${COLOR_RESET}"
  echo

}
