#! /bin/bash
# 
# Do a more sane apply-all via terragrunt

function argparse {
  PARAMS=""
  while (( "$#" )); do
    case "$1" in
      -h|--help)
        echo Usage: $0 '[-l|--local] [-t|--test] [-s|--skipqualys] [-d|--debug]'
        exit 0
        ;;
      -t|--test)
        TESTING="/bin/echo TESTING: "
        shift
        ;;
      -l|--local)
        LOCAL="1"
        shift
        ;;
      -n|--notlocal)
        NOTLOCAL="1"
        shift
        ;;
      -d|--debug)
        >&2 echo debug: Enabling debugging..
        DEBUG=1
        shift
        ;;
      -s|--skipqualys)
        SKIPQUALYS=1
        shift
        ;;
#      -p|--only-path)
#        if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
#          ONLY_PATH=$2
#          shift 2
#        else
#          echo "Error: Argument for $1 is missing" >&2
#          exit 1
#        fi
#        ;;
      -*|--*=) # unsupported flags
        echo "Error: Unsupported flag $1" >&2
        exit 1
        ;;
      *) # preserve positional arguments
        PARAMS="$PARAMS $1"
        shift
        ;;
    esac
  done
  # set positional arguments in their proper place
  eval set -- "$PARAMS"

  if [[ $LOCAL && $NOTLOCAL ]]; then
    echo ""
    echo "ERROR: Cannot specify both '--local' and '--nonlocal'. Pick one."
    exit 1
  fi

  if [[ $LOCAL ]]; then
    TERRAGRUNT_BIN=`which terragrunt-local`
  else
    if [[ $NOTLOCAL ]]; then
      [[ $DEBUG == 1 ]] && >&2 echo debug: Not local specified, not prompting.
# # This turned out to be annoying, I _usually_ run it with --notlocal
#    else
#      read -p "Local not specified. Specify '--notlocal' to skip this question. Are you sure? [Y/n]? " -n 1 -r
#      echo ""
#      if [[ $REPLY =~ ^[Nn]$ ]]
#      then
#          echo Exiting...
#          exit 1
#      fi
    fi
    TERRAGRUNT_BIN=`which terragrunt`
  fi
  if [[ ! -x $TERRAGRUNT_BIN ]]; then
    >&2 echo "Error: terragrunt executable ($TERRAGRUNT_BIN) not found or not executable."
    exit 4
  fi
}

# Main
argparse $*

SHORT_PWD=$( basename ${PWD}  )
PARENT_PWD=$( basename $( cd .. && pwd ) )
[[ $DEBUG == 1 ]] && >&2 echo debug: PWD=$PWD
[[ $DEBUG == 1 ]] && >&2 echo debug: SHORT_PWD=$SHORT_PWD

# Sanity Checking
if [[ $SHORT_PWD == "000-skeleton" ]]; then
  >&2 echo Error: Cannot run from skeleton directory. Exiting...
  exit 1
fi

if [[ $SHORT_PWD =~ ^[0-9]{3}-.* ]]; then
  >&2 echo Error: We appear to be in a module directory. Please run from the account directory you wish to update. Exiting...
  exit 2
fi

if [[ ! $PARENT_PWD =~ ^aws ]]; then
  >&2 echo Error: We do not appear to be in an account directory. Failing...
  exit 3
fi

for i in `seq -f "%g*" 0 9 | sort -n`; do
  EXITCODE=1 # Assume error
  MODULE=$( basename $i )
  if [[ -d $MODULE ]]; then
    echo "====================================================================================="
    echo "Processing module $MODULE..."
    echo "====================================================================================="
    if [[ $SKIPQUALYS == 1 && $MODULE =~ qualys ]]; then
      echo "Skipping due to skipqualys flag"
      echo ""
      continue
    else
     [[ $DEBUG == 1 ]] && echo  "Not qualys - SKIPQUALYS = ${SKIPQUALYS}; Module = ${MODULE}"
    fi
    pushd . > /dev/null
    cd $MODULE
    if [[ $(basename $(pwd)) =~ regional ]]; then
      echo "=========== We are in a regional directory, recursing..."
      for i in *; do
        if [[ -d $i ]]; then
          echo "========== Region: $i"
          pushd . > /dev/null
          cd $i
          [[ $TESTING ]] && ${TERRAGRUNT_BIN} plan  # Run a plan if testing
          [[ $TESTING ]] || ${TERRAGRUNT_BIN} init  # Run an init and apply
          [[ $TESTING ]] || ${TERRAGRUNT_BIN} apply
          EXITCODE=$?
          popd > /dev/null
          echo "========== Region completed: $i"
        fi
      done
    elif [[ -f DISABLED ]]; then
      echo Skipping module due to \"DISABLED\" file.
      EXITCODE=0
    else
      [[ $TESTING ]] && ${TERRAGRUNT_BIN} plan  # Run a plan if testing
      [[ $TESTING ]] || ${TERRAGRUNT_BIN} init  # Run an init and apply otherwise
      [[ $TESTING ]] || ${TERRAGRUNT_BIN} apply
      EXITCODE=$?
    fi
    popd > /dev/null
    echo "=======================================DONE=========================================="
    echo ""
    echo ""

    if [[ $EXITCODE != 0 ]]; then
      # Prompt to continue after each module. Easier than ctrl-c...
      read -p "Terragrunt completed. Continue to next module [Y/n]? " -n 1 -r
      echo ""
      if [[ $REPLY =~ ^[Nn]$ ]]
      then
          echo Exiting...
          exit 1
      fi
    fi
  fi
done

echo Finished.
exit 0
