#!/usr/bin/env bash
set -xeuo pipefail

ROOT=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
source "${ROOT}/lib.sh"

remote_config=${CONFIG_PATH}
local_config=/tmp/base-config.yaml

output_bucket_endpoint=$(get_oss_bucket_endpoint "$remote_config")
aliyun oss cp "${remote_config}" "${local_config}" --endpoint=$output_bucket_endpoint -f

action=$(yq '.jobOptions.iam.action // "apply"' "${local_config}")
output_command="terraform output -json"
if [[ "${action}" == "apply" ]]; then
  action="apply -auto-approve"
elif [[ "${action}" == "plan" ]]; then
  action="plan -out=tfplan.binary"
  output_command="terraform show -json tfplan.binary | jq '(.planned_values.outputs // {} | with_entries(.value.value = if .value.value == null then \"known-after-apply\" else .value.value end) )'"
fi

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}")
controlplane_account=$(yq '.alicloud.controlplaneAccount' "${local_config}")
dataplane_accounts_json=$(yq -ojson '.alicloud.dataplaneAccounts' "${local_config}" | jq -c '.')
dataplane_accounts=$(yq -ojson '.alicloud.dataplaneAccounts' "${local_config}" | jq -r '.[]')
is_byoc=$(yq '.jobOptions.isByoc // "false"' "${local_config}")
job_id=$(yq '.jobId' "${local_config}")
remote_output=$(yq '.outputPath' "${local_config}")
local_output=/tmp/output.yaml
resourceOwnerTag=$(yq '.jobOptions.resourceOwnerTag' "${local_config}")

oidc_issuer=$(yq '.k8s.oidcIssuer' "${local_config}")
oidc_arn=$(get_oidc_arn "$cluster")

tf_directory="${ROOT}/iam_tf"
tf_oss_bucket=$(yq '.terraformStateBucket' "${local_config}")
tf_oss_region=$(get_oss_bucket_region "oss://${tf_oss_bucket}")

tf_common_config="-backend-config=bucket=${tf_oss_bucket} -backend-config=region=${tf_oss_region}"

# Provision cert-manager iam role in controlplane account
module_path="cert-manager/controlplane"
cd "${tf_directory}/${module_path}"
tf_state_prefix="${env}/${module_path}"
tf_state_key="${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init $tf_common_config -backend-config="prefix=${tf_state_prefix}" -backend-config="key=${tf_state_key}"
terraform ${action} -var="env=${env}" \
  -var="oidc_issuer=${oidc_issuer}" \
  -var="oidc_arn=${oidc_arn}" \
  -var="logical_region_name=${logicalRegionName}" \
  -var="auto_deploy_owner_tag=${resourceOwnerTag}"
cert_manager_role_id=$(eval $output_command | jq '.role_id.value')
cert_manager_role_arn=$(eval $output_command | jq '.role_arn.value')
cert_manager_role_name=$(eval $output_command | jq '.role_name.value')

# Provision external-secrets-operator iam role in controlplane account
module_path="external-secrets-operator/controlplane"
cd "${tf_directory}/${module_path}"
tf_state_prefix="${env}/${module_path}"
tf_state_key="${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init $tf_common_config -backend-config="prefix=${tf_state_prefix}" -backend-config="key=${tf_state_key}"
terraform ${action} -var="env=${env}"\
  -var="oidc_issuer=${oidc_issuer}" \
  -var="oidc_arn=${oidc_arn}" \
  -var="logical_region_name=${logicalRegionName}" \
  -var="auto_deploy_owner_tag=${resourceOwnerTag}"
external_secrets_operator_role_id=$(eval $output_command | jq '.role_id.value')
external_secrets_operator_role_arn=$(eval $output_command | jq '.role_arn.value')
external_secrets_operator_role_name=$(eval $output_command | jq '.role_name.value')

# Provision dataplane-manager iam role in controlplane account
module_path="dataplane-manager/controlplane"
cd "${tf_directory}/${module_path}"
tf_state_prefix="${env}/${module_path}"
tf_state_key="${controlplane_account}-${env}-${logicalRegionName}-tfstate.json"
terraform init $tf_common_config -backend-config="prefix=${tf_state_prefix}" -backend-config="key=${tf_state_key}"
terraform ${action} -var="env=${env}"\
  -var="oidc_issuer=${oidc_issuer}" \
  -var="oidc_arn=${oidc_arn}" \
  -var="logical_region_name=${logicalRegionName}" \
  -var="auto_deploy_owner_tag=${resourceOwnerTag}"
dataplane_manager_role_id=$(eval $output_command | jq '.role_id.value')
dataplane_manager_role_arn=$(eval $output_command | jq '.role_arn.value')
dataplane_manager_role_name=$(eval $output_command | jq '.role_name.value')

# Provision dataplane-manager-assumed role in dataplane accounts
module_path="dataplane-manager/dataplane"
cd "${tf_directory}/${module_path}"
dataplane_manager_controlplane_role_arns="[${dataplane_manager_role_arn}]"
dataplane_manager_assumed_roles="[]"
for acct in ${dataplane_accounts[@]}; do
  tf_state_prefix="${env}/${module_path}"
  tf_state_key="${acct}-${env}-${logicalRegionName}-tfstate.json"
  terraform init $tf_common_config -backend-config="prefix=${tf_state_prefix}" -backend-config="key=${tf_state_key}"
  terraform ${action} -var="env=${env}" -var="account=${acct}" \
    -var="controlplane_role_arns=${dataplane_manager_controlplane_role_arns}" \
    -var="logical_region_name=${logicalRegionName}" \
    -var="auto_deploy_owner_tag=${resourceOwnerTag}"
  assumed_role_id=$(eval $output_command | jq -r '.role_id.value')
  assumed_role_name=$(eval $output_command | jq -r '.role_name.value')
  assumed_role_arn=$(eval $output_command | jq -r '.role_arn.value')
  dataplane_manager_assumed_roles=$(echo $dataplane_manager_assumed_roles | \
    jq --arg id "$assumed_role_id" \
       --arg name "$assumed_role_name" \
       --arg arn "$assumed_role_arn" \
       '. += [{"roleId":$id,"roleName":$name,"roleArn":$arn}]' \
    )
done

cat <<EOF > "${local_output}"
dataplaneManager:
  roleId: ${dataplane_manager_role_id}
  roleName: ${dataplane_manager_role_name}
  roleArn: ${dataplane_manager_role_arn}
  assumedRoleName: ${assumed_role_name}
certManager:
  roleId: ${cert_manager_role_id}
  roleName: ${cert_manager_role_name}
  roleArn: ${cert_manager_role_arn}
externalSecretsOperator:
  roleId: ${external_secrets_operator_role_id}
  roleName: ${external_secrets_operator_role_name}
  roleArn: ${external_secrets_operator_role_arn}
dataplaneManagerAssumedRoles: ${dataplane_manager_assumed_roles}
EOF
echo "iam output:"
cat "${local_output}"
echo "Write output to oss..."
aliyun oss cp "${local_output}" "${remote_output}" --endpoint=$output_bucket_endpoint -f
