#!/usr/bin/env bash
set -euo pipefail
# This script should be idempotent and retriable
# It's used to deploy a new region
# When adding a new dataplane aws account, this script should be
# invoked several times, each with a single region
action=${1:-destroy}
remote_config=${CONFIG_PATH}
local_config=/tmp/base-config.yaml

bucket_name=${remote_config#s3://}
bucket_name=${bucket_name%%/*}
output_bucket_region=$(aws s3api get-bucket-location --bucket=$bucket_name --query="LocationConstraint" \
  --region=us-west-2 --output=text --no-cli-pager)
aws s3 cp "${remote_config}" "${local_config}" --region=$output_bucket_region

cloud=$(yq '.cloudProvider' "${local_config}")
env=$(yq '.env' "${local_config}")
globalEnv=$(yq ".globalEnv // \"$env\"" "${local_config}")
region=$(yq '.region' "${local_config}")
logicalRegionName=$(yq '.name' "${local_config}")
cluster=$(yq '.k8s.name' "${local_config}")
eks_oidc=$(yq '.k8s.oidcIssuer' "${local_config}" | sed -E 's/^\s*.*:\/\///g')
controlplane_account=$(yq '.aws.controlplaneAccount' "${local_config}")
dataplane_accounts_json=$(yq -ojson '.aws.dataplaneAccounts' "${local_config}" | jq -c '.')
dataplane_accounts=$(yq -ojson '.aws.dataplaneAccounts' "${local_config}" | jq -r '.[]')
job_id=$(yq '.jobId' "${local_config}")
remote_output=$(yq '.outputPath' "${local_config}")
local_output=/tmp/output.yaml
ROOT=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
tf_directory="${ROOT}/../iam_tf"
tf_s3_bucket=$(yq '.terraformStateBucket' "${local_config}")
tf_s3_region=$(aws s3api get-bucket-location --bucket $tf_s3_bucket --region $region --query "LocationConstraint" --output text)

remote_iam_config=$(yq '.jobOutput.iam' "${local_config}")
local_iam_config=/tmp/iam-config.yaml
aws s3 cp ${remote_iam_config} ${local_iam_config} --region=$output_bucket_region

crossplane_role_arn=$(yq '.crossplaneAwsProvider.roleArn' "${local_iam_config}")
cluster_controller_role_arn=$(yq '.clusterController.roleArn' "${local_iam_config}")
readonly_cluster_controller_role_arn=$(yq '.clusterController.readonlyRoleArn' "${local_iam_config}")
cluster_controller_xp_controlplane_role_arn=$(yq '.clusterController.globalRoleArn' "${local_iam_config}")
region_server_role_arn=$(yq '.regionServer.roleArn' "${local_iam_config}")
region_server_xp_controlplane_role_arn=$(yq '.regionServer.globalRoleArn' "${local_iam_config}")
dm_controllerr_role_arn=$(yq '.tcidm.dmRoleArn' "${local_iam_config}")
import_controllerr_role_arn=$(yq '.tcidm.importRoleArn' "${local_iam_config}")

# Provision eks-service iam role in dataplane account
module_path="eks-service/dataplane"
cd "${tf_directory}/${module_path}"
eks_service_role_name="${env}-${logicalRegionName}-eks-service-role"
for acct in ${dataplane_accounts[@]}; do
  tf_state="${module_path}/${acct}-${env}-${logicalRegionName}-tfstate.json"
  terraform init -reconfigure -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
  terraform destroy -auto-approve -var="role_name=${eks_service_role_name}" -var="account=${acct}"
done


# Provision cluster-controller assumed role in dataplane accounts
# DEPENDON: ${cluster_controller_controlplane_role_arns}
module_path="cluster-controller/dataplane"
cd "${tf_directory}/${module_path}"
cluster_controller_controlplane_role_arns="[\"${cluster_controller_role_arn}\", \"${cluster_controller_xp_controlplane_role_arn}\", \"${crossplane_role_arn}\"]" # $crossplane_role_arn has removed quote
readonly_cluster_controller_controlplane_role_arns="[\"${readonly_cluster_controller_role_arn}\"]"
for acct in ${dataplane_accounts[@]}; do
  tf_state="${module_path}/${acct}-${env}-${logicalRegionName}-tfstate.json"
  terraform init -reconfigure -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
  terraform destroy -auto-approve -var="env=${env}" -var="account=${acct}" \
    -var="controlplane_role_arns=${cluster_controller_controlplane_role_arns}" \
    -var="readonly_controlplane_role_arns=${readonly_cluster_controller_controlplane_role_arns}" \
    -var="logical_region_name=${logicalRegionName}"
done

# Provision cluster-controller iam role in controlplane account
# DEPENDON: crossplane_role_arn
module_path="cluster-controller/controlplane"
cd "${tf_directory}/${module_path}"
tf_state="${module_path}/${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
terraform destroy -auto-approve -var="env=${env}" \
  -var="controlplane_account=${controlplane_account}" \
  -var="dataplane_accounts=${dataplane_accounts_json}" \
  -var="eks_oidc=${eks_oidc}" \
  -var="crossplane_role_arn=${crossplane_role_arn}" \
  -var="logical_region_name=${logicalRegionName}"

# Provision region-server assumed role in dataplane accounts
# DEPENDON: ${region_server_controlplane_role_arns}
module_path="region-server/dataplane"
cd "${tf_directory}/${module_path}"
region_server_controlplane_role_arns="[\"${region_server_role_arn}\", \"${region_server_xp_controlplane_role_arn}\", \"${crossplane_role_arn}\"]" # $crossplane_role_arn has removed quote
for acct in ${dataplane_accounts[@]}; do
  tf_state="${module_path}/${acct}-${env}-${logicalRegionName}-tfstate.json"
  terraform init -reconfigure -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
  terraform destroy -auto-approve -var="env=${env}" -var="account=${acct}" \
    -var="controlplane_role_arns=${region_server_controlplane_role_arns}" \
    -var="logical_region_name=${logicalRegionName}"
done

# Provision region-server iam role in controlplane account
# DEPENDON: crossplane_role_arn
module_path="region-server/controlplane"
cd "${tf_directory}/${module_path}"
tf_state="${module_path}/${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
terraform destroy -auto-approve -var="env=${env}" \
  -var="controlplane_account=${controlplane_account}" \
  -var="dataplane_accounts=${dataplane_accounts_json}" \
  -var="eks_oidc=${eks_oidc}" \
  -var="crossplane_role_arn=${crossplane_role_arn}" \
  -var="logical_region_name=${logicalRegionName}"

# Provision tcidm assumed role in dataplane accounts
module_path="tcidm/dataplane"
cd "${tf_directory}/${module_path}"
dm_controller_controlplane_role_arns="[\"${dm_controllerr_role_arn}\", \"${crossplane_role_arn}\"]" # $crossplane_role_arn has removed quote
import_controller_controlplane_role_arns="[\"${import_controllerr_role_arn}\", \"${crossplane_role_arn}\"]" # $crossplane_role_arn has removed quote
for acct in ${dataplane_accounts[@]}; do
  tf_state="${module_path}/${acct}-${env}-${logicalRegionName}-tfstate.json"
  terraform init -reconfigure -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
  terraform destroy -auto-approve -var="env=${env}" -var="account=${acct}" \
    -var="dm_controlplane_role_arns=${dm_controller_controlplane_role_arns}" \
    -var="import_controlplane_role_arns=${import_controller_controlplane_role_arns}" \
    -var="logical_region_name=${logicalRegionName}"
done
# Provision tcidm iam role in controlplane account
module_path="tcidm/controlplane"
cd "${tf_directory}/${module_path}"
tf_state="${module_path}/${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
terraform destroy -auto-approve -var="env=${env}" \
  -var="controlplane_account=${controlplane_account}" \
  -var="dataplane_accounts=${dataplane_accounts_json}" \
  -var="eks_oidc=${eks_oidc}" \
  -var="logical_region_name=${logicalRegionName}"

# Provision crossplane iam role in controlplane account
module_path="crossplane-aws-provider/controlplane"
cd "${tf_directory}/${module_path}"
tf_state="${module_path}/${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
terraform destroy -auto-approve -var="env=${env}" \
  -var="controlplane_account=${controlplane_account}" \
  -var="eks_oidc=${eks_oidc}" \
  -var="logical_region_name=${logicalRegionName}"


# Provision cert-manager iam role in controlplane account
module_path="cert-manager/controlplane"
cd "${tf_directory}/${module_path}"
tf_state="${module_path}/${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
terraform destroy -auto-approve -var="env=${env}" \
  -var="controlplane_account=${controlplane_account}" \
  -var="eks_oidc=${eks_oidc}" \
  -var="logical_region_name=${logicalRegionName}"

# Provision external-secrets-operator iam role in controlplane account
module_path="external-secrets-operator/controlplane"
cd "${tf_directory}/${module_path}"
tf_state="${module_path}/${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
terraform destroy -auto-approve -var="env=${env}" -var="secret_prefix=${globalEnv}" \
  -var="controlplane_account=${controlplane_account}" \
  -var="eks_oidc=${eks_oidc}" \
  -var="logical_region_name=${logicalRegionName}"

# Provision aws-lb-controller iam role in controlplane account
module_path="aws-load-balancer-controller/controlplane"
cd "${tf_directory}/${module_path}"
tf_state="${module_path}/${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
terraform destroy -auto-approve -var="env=${env}" \
  -var="controlplane_account=${controlplane_account}" \
  -var="eks_oidc=${eks_oidc}" \
  -var="logical_region_name=${logicalRegionName}"

# Provision cluster autoscaler iam role in controlplane account
module_path="cluster-autoscaler/controlplane"
cd "${tf_directory}/${module_path}"
tf_state="${module_path}/${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
terraform destroy -auto-approve -var="env=${env}" \
  -var="controlplane_account=${controlplane_account}" \
  -var="eks_oidc=${eks_oidc}" \
  -var="logical_region_name=${logicalRegionName}"

# Provision dp-provider iam role in controlplane account
module_path="dp-provider/controlplane"
cd "${tf_directory}/${module_path}"
tf_state="${module_path}/${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
terraform destroy -auto-approve -var="env=${env}" \
  -var="controlplane_account=${controlplane_account}" \
  -var="eks_oidc=${eks_oidc}" \
  -var="logical_region_name=${logicalRegionName}"

vector_role_arn=""
assume_o11y_role_arn=$(yq -ojson '.jobOptions.vector.o11yRoleArn' "${local_config}" | jq -r '.[]')
module_path="vector-agent/controlplane"
cd "${tf_directory}/${module_path}"
tf_state="${module_path}/${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init -backend-config="bucket=${tf_s3_bucket}" -backend-config="key=${tf_state}" -backend-config="region=${tf_s3_region}"
terraform destroy -auto-approve -var="env=${env}" \
  -var="logical_region_name=${logicalRegionName}" \
  -var="controlplane_account=${controlplane_account}" \
  -var="assume_o11y_role_arn=${assume_o11y_role_arn}" \
  -var="eks_oidc=${eks_oidc}"
