#!/usr/bin/env bash

profile_name_for () {
  local root_profile="$1" env="$2"

  if [[ $env == "root" ]]
  then
    echo "$root_profile"
  else
    echo "${root_profile}-${env}"
  fi
}

apply () {
  terraform apply ${@-} "plan" && rm "plan"
}


#
# V1
#

onboard () {
  local root_profile profile

  echo "What AWS profile would you like to use as your root profile?"
    read -p "> " root_profile
  echo

  echo $root_profile > .fenna/root_profile

  local backend_env=$(cat .fenna/backend/env)
  local backend_profile=$(profile_name_for $root_profile $backend_env)

  echo $backend_profile > .fenna/backend/profile

  if [[ -f ".fenna/sandbox" ]]
  then
    local suffix
    local sandbox_env=$(cat .fenna/sandbox)

    profile="${root_profile}-${sandbox_env}"

    echo "What suffix would you like to use to distinguish your resources in the sandbox?"
      read -p "> " suffix
    echo

    echo $suffix > .fenna/suffix
    touch "${sandbox_env}.tfvars"
    touch user.tfvars
  else
    local target_env=$(readlink .fenna/backend/current.tfvars | sed -e 's/\.\.\/backends\/\(.*\)\.tfvars/\1/')
    profile=$(profile_name_for $root_profile $target_env)
  fi

  echo $profile > .fenna/profile
}

init () {
  local backend_profile=$(cat .fenna/backend/profile)
  local suffix

  if [[ -f ".fenna/suffix" ]]
  then
    suffix=$(cat .fenna/suffix)
  fi

  if [[ -f ".fenna/sandbox" ]] && [[ ! -z "$suffix" ]]
  then
    terraform init \
      -backend-config .fenna/backend/current.tfvars \
      -backend-config "profile=${backend_profile}" \
      -backend-config "key=$(cat .fenna/service_name)-${suffix}/terraform.tfstate" \
      ${@-}
  else
    terraform init \
      -backend-config .fenna/backend/current.tfvars \
      -backend-config "profile=${backend_profile}" \
      -backend-config "key=$(cat .fenna/service_name)/terraform.tfstate" \
      ${@-}
  fi
}

plan () {
  local profile=$(cat .fenna/profile)
  local root_profile=$(cat .fenna/root_profile)
  local service_name=$(cat .fenna/service_name)

  if [[ -f ".fenna/sandbox" ]]
  then
    local sandbox_env=$(cat .fenna/sandbox)
    local suffix

    if [[ -f ".fenna/suffix" ]]
    then
      suffix=$(cat .fenna/suffix)
    fi

    terraform plan \
      -var "profile=${profile}" \
      -var "root_profile=${root_profile}" \
      -var "service_name=${service_name}" \
      -var "suffix=${suffix}" \
      -var-file "${sandbox_env}.tfvars" \
      -var-file "user.tfvars" \
      -out "plan" \
      ${@-}
  else
    terraform plan \
      -var "profile=${profile}" \
      -var "root_profile=${root_profile}" \
      -var "service_name=${service_name}" \
      -out "plan" \
      ${@-}
  fi
}


#
# V2
#

v2_backends () {
  if [[ -d ".fenna/backends" ]]
  then
    ls -1 .fenna/backends | grep ".tfvars" | sed -e 's/\.tfvars$//'
  fi
}

v2_targets () {
  if [[ -d ".fenna/targets" ]]
  then
    ls -1 .fenna/targets
  fi
}

v2_set_target () {
  local name=$1

  rm -f .fenna/target
  ln -sf "targets/${name}" .fenna/target

  rm -f .terraform
  ln -sf ".fenna/targets/${name}/.terraform" .terraform

  echo $name
}

v2_migrate () {
  cp -R .fenna .fenna-bak

  echo "2" > .fenna/version

  local backend=$(readlink .fenna/backend/current.tfvars | sed -e 's/\.\.\/backends\/\(.*\)\.tfvars/\1/')
  rm .fenna/backend/current.tfvars

  local target

  if [[ -f ".fenna/sandbox" ]]
  then
    target=$(cat .fenna/sandbox)
    rm .fenna/sandbox
  else
    target="${backend}"
  fi

  mkdir -p ".fenna/targets/${target}"
  mv .fenna/profile ".fenna/targets/${target}/profile"

  mv .fenna/backend ".fenna/targets/${target}/backend"
  ln -sf "../../../backends/${backend}.tfvars" ".fenna/targets/${target}/backend/config.tfvars"

  if [[ -f ".fenna/suffix" ]]
  then
    local suffix=$(cat .fenna/suffix)

    if [[ -z "$suffix" ]]
    then
      rm .fenna/suffix
    else
      mv .fenna/suffix ".fenna/targets/${target}/suffix"
    fi
  fi

  cp -R .terraform .terraform-bak
  mv .terraform ".fenna/targets/${target}/.terraform"

  rm .fenna/.gitignore

  cat > .fenna/.gitignore <<EOS
target
targets/**/.terraform
targets/**/backend/profile
targets/**/profile
targets/**/suffix
root_profile
EOS

  rm -f fenna_variables.tf

  cat > fenna_variables.tf <<EOS
variable "assume_role_arn" {
  default = ""
}

variable "profile" {
  default = ""
}

variable "root_profile" {
  default = ""
}

variable "service_name" {}

variable "suffix" {
  default = ""
}

locals {
  suffix = var.suffix == "" ? "" : "-\${var.suffix}"
}
EOS

  touch "${target}.tfvars"

  cat <<EOS >> .gitignore
*.sensitive.tfvars
EOS

  touch "${target}.sensitive.tfvars"

  v2_set_target $target
}

v2_configure_target () {
  local name="$1"

  local root_profile=$(cat .fenna/root_profile)
  local backend_env=$(cat ".fenna/targets/${name}/backend/env")
  local backend_profile=$(profile_name_for $root_profile $backend_env)

  echo $backend_profile > ".fenna/targets/${name}/backend/profile"

  local target_env=$(readlink ".fenna/targets/${name}/backend/config.tfvars" | sed -e 's/\.\.\/\.\.\/\.\.\/backends\/\(.*\)\.tfvars/\1/')
  local profile=$(profile_name_for $root_profile $target_env)

  echo $profile > ".fenna/targets/${name}/profile"

  local suffix

  echo "What suffix would you like to use to distinguish your state and resources within this target?"
    read -p "> " suffix
  echo

  if [[ ! -z "$suffix" ]]
  then
    echo $suffix > ".fenna/targets/${name}/suffix"
  fi
}

v2_target () {
  local name="$1"

  if [[ -d ".fenna/targets/${name}" ]]
  then
    if [[ -f ".fenna/targets/${name}/profile" ]] && [[ -f ".fenna/targets/${name}/backend/profile" ]]
    then
      v2_set_target $name
    else
      v2_configure_target $name
      v2_set_target $name
    fi
  else
    mkdir -p ".fenna/targets/${name}/backend"
    mkdir ".fenna/targets/${name}/.terraform"

    local environments=$(v2_backends)
    local backend

    echo "Which backend would you like to use? [$(echo $environments)]"
      read -p "> " backend
    echo

    ln -sf "../../../backends/${backend}.tfvars" ".fenna/targets/${name}/backend/config.tfvars"

    local backend_env

    echo "Where is your backend stored? [$(echo $environments)]"
      read -p "> " backend_env
    echo

    echo $backend_env > ".fenna/targets/${name}/backend/env"

    touch "${name}.tfvars"
    touch "${name}.sensitive.tfvars"

    v2_configure_target $name
    v2_set_target $name
  fi
}

v2_onboard () {
  local root_profile

  echo "What AWS profile would you like to use as your root profile?"
    read -p "> " root_profile
  echo

  echo $root_profile > .fenna/root_profile

  touch user.tfvars

  local targets=$(v2_targets)

  if [[ ! -z "$targets" ]]
  then
    for t in "${targets[@]}"
    do
      touch "${t}.sensitive.tfvars"
    done

    local target

    echo "Which target would you like to use? [$(echo $targets)]"
      read -p "> " target
    echo

    if [[ ! -z "$target" ]]
    then
      v2_target $target
    fi
  fi
}

v2_bootstrap () {
  if [[ ! -d ".fenna" ]]
  then
    mkdir -p .fenna/targets
  fi

  echo "2" > .fenna/version

  cat > .fenna/.gitignore <<EOS
target
targets/**/.terraform
targets/**/backend/profile
targets/**/profile
targets/**/suffix
root_profile
EOS

  local service_name

  echo "What is this service named?"
    read -p "> " service_name
  echo

  echo $service_name > .fenna/service_name

  cat > fenna_variables.tf <<EOS
variable "assume_role_arn" {
  default = ""
}

variable "profile" {
  default = ""
}

variable "root_profile" {
  default = ""
}

variable "service_name" {}

variable "suffix" {
  default = ""
}

locals {
  suffix = var.suffix == "" ? "" : "-\${var.suffix}"
}
EOS

  cat <<EOS >> .gitignore
*.tfstate*
.terraform
plan
*.sensitive.tfvars
user.tfvars
EOS

  if [[ ! -d ".fenna/backends" ]]
  then
    local repository_url

    echo "What's your backend config repository's URL?"
      read -p "> " repository_url
    echo

    git submodule add $repository_url .fenna/backends
    echo
  fi

  v2_onboard
}

v2_init () {
  local backend_profile=$(cat .fenna/target/backend/profile)
  local suffix

  if [[ -f ".fenna/target/suffix" ]]
  then
    suffix=$(cat .fenna/target/suffix)
  fi

  local state_key_root=$(cat .fenna/service_name)

  if [[ ! -z "$suffix" ]]
  then
    state_key_root="${state_key_root}-${suffix}"
  fi

  terraform init \
    -backend-config .fenna/target/backend/config.tfvars \
    -backend-config "profile=${backend_profile}" \
    -backend-config "key=${state_key_root}/terraform.tfstate" \
    ${@-}
}

v2_plan () {
  local profile=$(cat .fenna/target/profile)
  local root_profile=$(cat .fenna/root_profile)
  local service_name=$(cat .fenna/service_name)
  local target=$(readlink .fenna/target | sed -e 's/targets\/\(.*\)/\1/')

  local suffix

  if [[ -f ".fenna/target/suffix" ]]
  then
    suffix=$(cat .fenna/target/suffix)
  fi

  terraform plan \
    -var "profile=${profile}" \
    -var "root_profile=${root_profile}" \
    -var "service_name=${service_name}" \
    -var "suffix=${suffix}" \
    -var-file "${target}.tfvars" \
    -var-file "${target}.sensitive.tfvars" \
    -var-file "user.tfvars" \
    -out "plan" \
    ${@-}
}


#
# Dispatch
#

cmd="$1"
shift

if [[ -f ".fenna/version" ]]
then
  case "$cmd" in
    backends) v2_backends ;;
    targets) v2_targets ;;
    bootstrap) v2_bootstrap ;;
    onboard) v2_onboard ;;
    target) v2_target "$1" ;;
    init) v2_init "$@" ;;
    plan) v2_plan "$@" ;;
    apply) apply "$@" ;;
  esac
else
  case "$cmd" in
    migrate) v2_migrate ;;
    bootstrap) v2_bootstrap ;;
    onboard) onboard ;;
    init) init "$@" ;;
    plan) plan "$@" ;;
    apply) apply "$@" ;;
  esac
fi