#!/usr/bin/env bash

#####################
## CHECK ARGUMENTS ##
#####################

usage () {
  usage_text="Usage: $(basename "$0") env stack-name cf-template
  where:
    env          - the env name 
    stack-name   - the stack name
    cf-template  - the template file
"
  echo "${usage_text}"
  exit 1
}

if [ "$1" == "help" ] || [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
  usage
fi

##########
## VARS ##
##########

CLOUDFORMATION_ENV=$1
CLOUDFORMATION_STACK_NAME=$2
CLOUDFORMATION_FILE=$3
STACK_NAME="${CLOUDFORMATION_STACK_NAME}-${CLOUDFORMATION_ENV}"

###############
## FUNCTIONS ##
###############

# Check stack exist
cloudformation_stack_exists () {
  echo "Checking if stack exists"

  if ! aws cloudformation describe-stacks --stack-name ${STACK_NAME}; then
    STACK_EXIST="False"
  else
    STACK_EXIST="True"
  fi
}
# Create stack
cloudformation_stack_create () {
  echo "Create Stack"
  aws cloudformation create-stack \
  --stack-name ${STACK_NAME} \
  --parameters ParameterKey=Environment,ParameterValue=${CLOUDFORMATION_ENV} \
  --template-body file://${CLOUDFORMATION_FILE} \
  --capabilities CAPABILITY_IAM \
  --capabilities CAPABILITY_NAMED_IAM
  
  echo "Waiting for stack to be created ..."
  aws cloudformation wait stack-create-complete \
  --stack-name ${STACK_NAME}
  
}

# Update stack
cloudformation_stack_update () {
  echo "Update Stack"
  set +e
  update_output=$( aws cloudformation update-stack \
  --stack-name ${STACK_NAME} \
  --parameters ParameterKey=Environment,ParameterValue=${CLOUDFORMATION_ENV} \
  --template-body file://${CLOUDFORMATION_FILE} \
  --capabilities CAPABILITY_IAM \
  --capabilities CAPABILITY_NAMED_IAM 2>&1)
  status=$?
  set -e

  echo "$update_output"

  if [ $status -ne 0 ] ; then

    # Don't fail for no-op update
    if [[ $update_output == *"ValidationError"* && $update_output == *"No updates"* ]] ; then
      echo -e "\nFinished create/update - no updates to be performed"
      exit 0
    else
      exit $status
    fi

  fi

  echo "Waiting for stack update to complete ..."
  aws cloudformation wait stack-update-complete \
  --stack-name ${STACK_NAME}
  
}

##########
## MAIN ##
##########
shopt -s failglob
set -eu -o pipefail

cloudformation_stack_exists

if [ "${STACK_EXIST}" == "False" ]; then
  cloudformation_stack_create
fi

if [ "${STACK_EXIST}" == "True" ]; then
  cloudformation_stack_update
fi

echo "Finished create/update successfully!"