#!/usr/bin/env bash

function gitops_cos_help() {
  [[ -n "$1" ]] && echo_warning "$1"
  reset_colors
  cat << EOM
Usage:
  mas gitops-cos [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:
  -a, --account-id ${COLOR_YELLOW}ACCOUNT_ID${TEXT_RESET}                                                  Account name that the cluster belongs to
  -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

IBM Maximo Application Suite:
  -m, --mas-instance-id ${COLOR_YELLOW}MAS_INSTANCE_ID${TEXT_RESET}                                    IBM Suite Maximo Application Suite Instance ID  
      --mas-config-dir ${COLOR_YELLOW}MAS_CONFIG_DIR${TEXT_RESET}                                      IBM Suite Maximo Application Suite config dir to hold config

COS Provider:
      --cos-action ${COLOR_YELLOW}COS_ACTION${TEXT_RESET}                                                  provision or deprovision
      --cos-type ${COLOR_YELLOW}COS_TYPE${TEXT_RESET}                                                      COS type, only ibm supported
      --cos-resourcegroup ${COLOR_YELLOW}COS_RESOURCEGROUP${TEXT_RESET}                                    IBM Cloud resource group to set
      --cos-apikey ${COLOR_YELLOW}COS_APIKEY${TEXT_RESET}                                                  IBM Cloud APIkey

Other Commands:
      -h, --help                                                                                           Show this help message
EOM
  [[ -n "$1" ]] && exit 1 || exit 0
}


function gitops_cos_noninteractive() {
  GITOPS_WORKING_DIR=$PWD/working-dir  
  SECRETS_KEY_SEPERATOR="/"

  while [[ $# -gt 0 ]]
  do
    key="$1"
    shift
    case $key in
      # GitOps Configuration
      -d|--dir)
        export GITOPS_WORKING_DIR=$1 && shift
        ;;
      -a|--account-id)
        export ACCOUNT_ID=$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
      -m|--mas-instance-id)
        export MAS_INSTANCE_ID=$1 && shift
        ;;
      --mas-config-dir)
        export MAS_CONFIG_DIR=$1 && shift
        ;;

      # COS Provider Selection
      --cos-action)
        export COS_ACTION=$1 && shift
        ;;
      --cos-type)
        export COS_TYPE=$1 && shift
        ;;
      --cos-resourcegroup)
        export COS_RESOURCEGROUP=$1 && shift
        ;;
      --cos-apikey)
        export COS_APIKEY=$1 && shift
        ;;

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


  [[ -z "$CLUSTER_ID" ]] && gitops_cos_help "CLUSTER_ID is not set"
  [[ -z "$COS_TYPE" ]] && gitops_cos_help "COS_TYPE is not set"
  if [[ "${COS_TYPE}" == "ibm" ]]; then
    [[ -z "$COS_APIKEY" ]] && gitops_cos_help "COS_APIKEY is not set"
  fi
  [[ -z "$ACCOUNT_ID" ]] && gitops_cos_help "ACCOUNT_ID is not set"
  [[ -z "$MAS_INSTANCE_ID" ]] && gitops_cos_help "MAS_INSTANCE_ID is not set"
  [[ -z "$MAS_CONFIG_DIR" ]] && gitops_cos_help "MAS_CONFIG_DIR is not set"

}

function gitops_cos() {
  # Take the first parameter off (it will be create-gitops)
  shift
  if [[ $# -gt 0 ]]; then
    gitops_cos_noninteractive "$@"
  else
    echo "Not supported yet"
    exit 1
    gitops_cos_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}/${CLUSTER_ID}
  TEMP_DIR=$GITOPS_CLUSTER_DIR/tmp-cos
  mkdir -p ${TEMP_DIR}
  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 "Cluster ID ............................ ${COLOR_MAGENTA}${CLUSTER_ID}"
  echo_reset_dim "Application Directory ................. ${COLOR_MAGENTA}${TEMP_DIR}"  
  reset_colors

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

  echo "${TEXT_DIM}"
  echo_h2 "COS" "    "
  echo_reset_dim "COS action  ........................... ${COLOR_MAGENTA}${COS_ACTION}"
  echo_reset_dim "COS type  ............................. ${COLOR_MAGENTA}${COS_TYPE}"
  if [[ "${COS_TYPE}" == "ibm" ]]; then
    echo_reset_dim "COS Resource Group  ................... ${COLOR_MAGENTA}${COS_RESOURCEGROUP}"
    echo_reset_dim "COS ApiKey ............................ ${COLOR_MAGENTA}${COS_APIKEY:0:8}<snip>"
  fi
  
  echo "${TEXT_DIM}"
  echo_h2 "IBM Maximo Application Suite" "    "
  echo_reset_dim "Instance ID ............................. ${COLOR_MAGENTA}${MAS_INSTANCE_ID}"
  echo_reset_dim "Config Dir  ............................. ${COLOR_MAGENTA}${MAS_CONFIG_DIR}"

  reset_colors

  AVP_TYPE=aws  # Support for IBM will be added later
  sm_login

  export MAS_INSTANCE_ID=${MAS_INSTANCE_ID:-CLUSTER_ID}

  if [[ "$COS_TYPE" == "ibm" ]]; then

    export COS_SECRET=${ACCOUNT_ID}${SECRETS_KEY_SEPERATOR}${CLUSTER_ID}${SECRETS_KEY_SEPERATOR}${MAS_INSTANCE_ID}${SECRETS_KEY_SEPERATOR}cos
    export ROLE_NAME=cos && ansible-playbook ibm.mas_devops.run_role

    rc=$?
    [ $rc -ne 0 ] && exit $rc

    # Extract the required details from the generated coscfg/secret.
    export COS_USERNAME
    COS_USERNAME=$(yq 'select(di == 0) | .data.username' $MAS_CONFIG_DIR/cos-ibm-system.yml | base64 -d)
    rc=$?
    [ $rc -ne 0 ] && exit $rc
    export COS_PASSWORD
    COS_PASSWORD=$(yq 'select(di == 0) | .data.password' $MAS_CONFIG_DIR/cos-ibm-system.yml | base64 -d)
    rc=$?
    [ $rc -ne 0 ] && exit $rc
    yq 'select(di == 1) | .spec' $MAS_CONFIG_DIR/cos-ibm-system.yml >> $TEMP_DIR/cos-info.yaml
    yq -i 'del(.config.credentials)' $TEMP_DIR/cos-info.yaml
    yq -i 'del(.displayName)' $TEMP_DIR/cos-info.yaml

    UNESCAPED_INFO="$(cat $TEMP_DIR/cos-info.yaml)"
    ESCAPED_INFO=${UNESCAPED_INFO//\"/\\\"}
    ESCAPED_INFO=${ESCAPED_INFO//$'\n'/\\n}

    TAGS="[{\"Key\": \"source\", \"Value\": \"gitops_cos\"}, {\"Key\": \"account\", \"Value\": \"${ACCOUNT_ID}\"}, {\"Key\": \"cluster\", \"Value\": \"${CLUSTER_ID}\"}]"
    sm_update_secret $COS_SECRET "{\"username\": \"$COS_USERNAME\", \"password\": \"$COS_PASSWORD\", \"info\": \"$ESCAPED_INFO\"}" "${TAGS}"
    rc=$?
    [ $rc -ne 0 ] && exit $rc


  elif [[ "$COS_TYPE" == "aws" ]]; then

    curl https://releases.hashicorp.com/terraform/1.9.2/terraform_1.9.2_linux_amd64.zip --output $TEMP_DIR/terraform_1.9.2_linux_amd64.zip
    rc=$?
    [ $rc -ne 0 ] && exit $rc

    unzip $TEMP_DIR/terraform_1.9.2_linux_amd64.zip -d $TEMP_DIR
    rc=$?
    [ $rc -ne 0 ] && exit $rc

    chmod +x $TEMP_DIR/terraform

    cat > $TEMP_DIR/main.tf <<EOF
    locals {
      name_prefix = "$ACCOUNT_ID"
    }

    output "s3c" {
      value     = module.s3a
      sensitive = false
    }

    output "s3a" {
      value     = module.s3a
      sensitive = false
    }

    output "s3l" {
      value     = module.s3l
      sensitive = false
    }

    output "s3db2" {
      value     = module.s3db2
      sensitive = false
    }

    module "s3c" {
      name_prefix = local.name_prefix
      source = "git::https://git:$GITHUB_PAT@github.ibm.com/maximoappsuite/mas-iac-aws-s3.git//module?ref=1.0.1"
      s3_bucket               = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3c"
      s3_encryption           = true
      s3_encryption_algorithm = "AES256"
      force_bucket_destroy    = true
    }

    module "s3a" {
      name_prefix = local.name_prefix
      source = "git::https://git:$GITHUB_PAT@github.ibm.com/maximoappsuite/mas-iac-aws-s3.git//module?ref=1.0.1"
      s3_bucket               = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3a"
      s3_encryption           = true
      s3_encryption_algorithm = "AES256"
      force_bucket_destroy    = true
    }

    module "s3l" {
      name_prefix = local.name_prefix
      source = "git::https://git:$GITHUB_PAT@github.ibm.com/maximoappsuite/mas-iac-aws-s3.git//module?ref=1.0.1"
      s3_bucket               = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3l"
      s3_encryption           = true
      s3_encryption_algorithm = "AES256"
      force_bucket_destroy    = true
    }

    module "s3db2" {
      name_prefix = local.name_prefix
      source = "git::https://git:$GITHUB_PAT@github.ibm.com/maximoappsuite/mas-iac-aws-s3.git//module?ref=1.0.1"
      s3_bucket               = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3db2"
      s3_encryption           = true
      s3_encryption_algorithm = "AES256"
      force_bucket_destroy    = true
    }

    output "s3c_access_point" {
      value     = module.s3c_access_point
      sensitive = false
    }

    output "s3a_access_point" {
      value     = module.s3a_access_point
      sensitive = false
    }

    output "s3l_access_point" {
      value     = module.s3l_access_point
      sensitive = false
    }

    output "s3db2_access_point" {
      value     = module.s3db2_access_point
      sensitive = false
    }

    module "s3c_access_point" {
      source = "git::https://git:$GITHUB_PAT@github.ibm.com/maximoappsuite/mas-iac-aws-s3-access-point.git//module?ref=1.0.10"
      name_prefix = local.name_prefix
      s3_access_point_bucket_id      = module.s3c.s3_bucket_id
      s3_bucket_arn                  = module.s3c.s3_bucket_arn
      s3_bucket_region               = module.s3c.s3_bucket_region
      s3_access_point_name           = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3c-access"
      s3_access_point_policy_actions = [ "s3:DeleteObject", "s3:GetObject", "s3:GetObjectAcl", "s3:PutObject", "s3:PutObjectAcl", "s3:ListBucket" ]
      s3_access_point_user           = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3c-user"
      mas_cluster_id                 = "$CLUSTER_ID"
      mas_instance_id                = "$MAS_INSTANCE_ID"
      secret_recovery_days           = 0
      secret_suffix                  = "cos"
      cos_secret_format              = true
    }

    module "s3a_access_point" {
      source = "git::https://git:$GITHUB_PAT@github.ibm.com/maximoappsuite/mas-iac-aws-s3-access-point.git//module?ref=1.0.10"
      name_prefix = local.name_prefix
      s3_access_point_bucket_id      = module.s3a.s3_bucket_id
      s3_bucket_arn                  = module.s3a.s3_bucket_arn
      s3_bucket_region               = module.s3a.s3_bucket_region
      s3_access_point_name           = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3a-access"
      s3_access_point_policy_actions = [ "s3:DeleteObject", "s3:GetObject", "s3:GetObjectAcl", "s3:PutObject", "s3:PutObjectAcl", "s3:ListBucket" ]
      s3_access_point_user           = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3a-user"
      mas_cluster_id                 = "$CLUSTER_ID"
      mas_instance_id                = "$MAS_INSTANCE_ID"
      secret_recovery_days           = 0
      secret_suffix                  = "manage_attachments/cos-attachments"
      manage_secret_format           = true
    }

    module "s3l_access_point" {
      source = "git::https://git:$GITHUB_PAT@github.ibm.com/maximoappsuite/mas-iac-aws-s3-access-point.git//module?ref=1.0.10"
      name_prefix = local.name_prefix
      s3_access_point_bucket_id      = module.s3l.s3_bucket_id
      s3_bucket_arn                  = module.s3l.s3_bucket_arn
      s3_bucket_region               = module.s3l.s3_bucket_region
      s3_access_point_name           = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3l-access"
      s3_access_point_policy_actions = [ "s3:DeleteObject", "s3:GetObject", "s3:GetObjectAcl", "s3:PutObject", "s3:PutObjectAcl", "s3:ListBucket" ]
      s3_access_point_user           = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3l-user"
      mas_cluster_id                 = "$CLUSTER_ID"
      mas_instance_id                = "$MAS_INSTANCE_ID"
      secret_recovery_days           = 0
      secret_suffix                  = "manage_logging/cos-logging"
      manage_secret_format           = true
    }

    module "s3db2_access_point" {
      source = "git::https://git:$GITHUB_PAT@github.ibm.com/maximoappsuite/mas-iac-aws-s3-access-point.git//module?ref=1.0.10"
      name_prefix = local.name_prefix
      s3_access_point_bucket_id      = module.s3db2.s3_bucket_id
      s3_bucket_arn                  = module.s3db2.s3_bucket_arn
      s3_bucket_region               = module.s3db2.s3_bucket_region
      s3_access_point_name           = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3db2-access"
      s3_access_point_policy_actions = [ "s3:DeleteObject", "s3:GetObject", "s3:GetObjectAcl", "s3:PutObject", "s3:PutObjectAcl", "s3:ListBucket" ]
      s3_access_point_user           = "${CLUSTER_ID}-${MAS_INSTANCE_ID}-s3db2-user"
      mas_cluster_id                 = "$CLUSTER_ID"
      mas_instance_id                = "$MAS_INSTANCE_ID"
      secret_recovery_days           = 0
      secret_suffix                  = "db2_backup"
      manage_secret_format           = true
    }
EOF

    cat > $TEMP_DIR/provider.tf <<EOF
    provider "aws" {
      region = "$SM_AWS_REGION"
    }
EOF

    cat > $TEMP_DIR/backend.tf <<EOF
    terraform {
      backend "s3" {
        bucket = "fvtsaas-automation-bucket"
        key = "${CLUSTER_ID}-${MAS_INSTANCE_ID}.tfstate"
        region = "us-east-1"
      }
    }
EOF

    echo $TEMP_DIR/terraform -chdir=$TEMP_DIR init -input=false
    $TEMP_DIR/terraform -chdir=$TEMP_DIR init -input=false
    rc=$?
    [ $rc -ne 0 ] && exit $rc

    echo $TEMP_DIR/terraform -chdir=$TEMP_DIR plan -input=false -out=tfplan
    $TEMP_DIR/terraform -chdir=$TEMP_DIR plan -input=false -out=tfplan
    rc=$?
    [ $rc -ne 0 ] && exit $rc

    # export TF_LOG="TRACE"
    echo $TEMP_DIR/terraform -chdir=$TEMP_DIR apply -auto-approve -input=false tfplan
    $TEMP_DIR/terraform -chdir=$TEMP_DIR apply -auto-approve -input=false tfplan
    rc=$?
    [ $rc -ne 0 ] && exit $rc

  fi

  rm -rf $TEMP_DIR
  exit 0
}
