#!/usr/bin/env bash

# If running locally, run this from the root directory of your terraform-infra repository checkout

# Set these environment variables:
# - MODULE_NAME
# - PR_NUMBER

set -u -e

git clone "https://${GITHUB_TOKEN}@github.com/theorchard/terraform-infra.git"
cd terraform-infra
git fetch origin "pull/${PR_NUMBER}/head:PR_${PR_NUMBER}"
git checkout "PR_${PR_NUMBER}"

CHANGED_FILE_DIRECTORIES=$(git --no-pager diff --name-only FETCH_HEAD $(git merge-base FETCH_HEAD master) | xargs dirname | sort | uniq)
for CHANGED_FILE_DIRECTORY in ${CHANGED_FILE_DIRECTORIES}; do
  pushd "${CHANGED_FILE_DIRECTORY}"

  # Generate a plan file and turn it into json
  rm -rf plan.txt plan.json .terraform
  tfswitch
  terraform init
  terraform plan -target module."${MODULE_NAME}" -out=plan.txt
  terraform show -json plan.txt > plan.json

  # Find the state file bucket and object prefix
  STATE_FILE_BUCKET=$(cat main.tf  | grep -i bucket | grep -i terraform-state | awk '{print $3}' | sed 's/"//g')
  STATE_FILE_LOCATION=$(cat main.tf | grep -i terraform.tfstate | awk '{print $3}' | sed 's/"//g')
  CURRENT_STATE_FILE_OBJECT_VERSION=$(aws s3api list-object-versions --bucket "${STATE_FILE_BUCKET}" --prefix "${STATE_FILE_LOCATION}" --query 'Versions[?IsLatest==`true`].VersionId' --output text)

  child_module_length=$(cat plan.json | jq '.planned_values.root_module.child_modules | length')

  # Handle modules both with a single secret (single child module) as well as ones
  # invoked with for_each (multiple child modules) by iterating through them
  for (( iterator=0; iterator<=child_module_length; iterator++ )); do
    json_module=$(cat plan.json | jq -r --argjson iterator "${iterator}" '.planned_values.root_module.child_modules[$iterator]')

    if [ "$(echo ${json_module} | jq -r '.resources[0].type')" = 'aws_secretsmanager_secret' ]; then
      secret_name=$(echo ${json_module} | jq -r '.resources[0].values.name')

      printf '%s\n' "Importing ${secret_name}"
      terraform_secret_resource_location="$(echo ${json_module} | jq -r '.resources[0].address')"
      terraform_secret_string_resource_location="$(echo ${json_module} | jq -r '.resources[1].address')"

      printf '%s\n' "Secret resource location is ${terraform_secret_resource_location}"
      # This is a quick solution to not exit the script if the secret already exists in the terraform state or cannot be found
      # TODO: pull the actual state contents and search for "${terraform_secret_resource_location}"
      set +e
      version=$(aws secretsmanager get-secret-value --secret-id "${secret_name}" --region us-east-1 --query 'VersionId' --output text)

      printf '%s\n' "Secret version is ${version}"
      printf '%s\n' "Secret string resource location is ${terraform_secret_string_resource_location}"
      terraform import "${terraform_secret_resource_location}" "${secret_name}"
      terraform import "${terraform_secret_string_resource_location}" "${secret_name}|${version}"
      set -e
    fi
  done

  # Now sanitize secret strings
  terraform state pull > terraform.tfstate
  printf '%s\n' "Sanitizing state file"
  python3 /opt/terraform/state_file_cleaner.py -b "${STATE_FILE_BUCKET}" -o "${STATE_FILE_LOCATION}" -v "${CURRENT_STATE_FILE_OBJECT_VERSION}"
  terraform state push terraform.tfstate
  printf '%s\n' "Pushed updated state file to remote state"

  # Clean up
  rm -rf plan.txt plan.json .terraform terraform.tfstate

  popd
done
