#!/usr/bin/env bash

# Quick script to bundle and ship a git branch to S3 
# 
# This script expects .aws/(config|credentials) to be configured
# for the user running this script, and will fail if they are not.

AWS_BINARY=$(which aws)
AWS_DEFAULT_REGION='us-east-1'
# This can be overridden with the -b option
BRANCH_NAME='master'
BUNDLE_NAME="$(basename $(pwd)).bundle"
# This should be set with the -e option
ENVIRONMENT='qa'
GIT_BINARY=$(which git)
# This can be overridden with the -k option
KMS_KEY="${ENVIRONMENT}_monolith_staged_configs"
LOGFILE_NAME='/var/tmp/staged_configs_post_commit_hook.log'
S3_BUCKET='nickelback'
S3_OBJECT_KEY="staged-configs/${KMS_KEY}"

function check_logfile {
  if [ -w "$(dirname ${LOGFILE_NAME})" ]; then 
    return 0
  else
    printf '%s\n' "Logfile directory is not writable." && exit 1
  fi
}

function logmessage {
  check_logfile
  printf '%s\n' " $(date +%c): ${1}" >> "${LOGFILE_NAME}"
  printf '%s\n' >> "${LOGFILE_NAME}"
}

function make_git_bundle {
  if [ -x "${GIT_BINARY}" ]; then
    if ${GIT_BINARY} status > /dev/null 2>&1; then
      logmessage "Creating ${BUNDLE_NAME}"
      if [ -f ${BUNDLE_NAME} ]; then
        logmessage "Found existing bundle. Removing..."
        rm -rf ${BUNDLE_NAME}
      fi
      ${GIT_BINARY} bundle create "${BUNDLE_NAME}" ${BRANCH_NAME}
      logmessage "${BUNDLE_NAME} created"
    else
      logmessage "Git repo not found or no commit log" && exit 1
    fi
  else
    logmessage "Git binary not found" && exit 1
  fi 
}

function encrypt_and_copy_bundle {
  if [ -x "${AWS_BINARY}" ]; then
    if ${AWS_BINARY} s3 cp "${BUNDLE_NAME}" s3://${S3_BUCKET}/${S3_OBJECT_KEY} --sse aws:kms --sse-kms-key-id alias/${KMS_KEY}; then
      logmessage "Copied ${BUNDLE_NAME} to s3://${S3_BUCKET}/${S3_OBJECT_KEY}. Removing local file..."
      rm -rf ${BUNDLE_NAME}
    else
      logmessage "S3 copy unsuccessful" && exit 1
    fi
  else
    logmessage "AWS cli not found" && exit 1
  fi
}

while getopts 'a:b:e:hk:' flag; do
  case "${flag}" in
  a) export AWS_DEFAULT_REGION="${OPTARG}" ;;
  b) BRANCH_NAME="${OPTARG}" ;;
  e) ENVIRONMENT="${OPTARG}" ;;
  h) printf '%s\n'
     printf '%s\n' "This script bundles and ships a git branch to S3."
     printf '%s\n' "The following options are supported:"
     printf '%s\n'
     printf '%s\n' "-h: Print this message"
     printf '%s\n'
     printf '%s\n' "-a (optional) Use the specified AWS region; the default is us-east-1"
     printf '%s\n' "-b (optional) Use the specified branch; the default is master"
     printf '%s\n' "-e (required) Specify an environment: options are qa and prod"
     printf '%s\n' "-k (optional) Use the specified AWS KMS key"
     printf '%s\n'
     printf '%s\n' "Example: ./staged_configs_post_commit_hook.sh -b test_branch -e qa"
     exit 0 ;;
  k) KMS_KEY="${OPTARG}" ;;
  *) printf "Unexpected option ${flag}\n"
     exit 1 ;;
  esac
done

if [ "${ENVIRONMENT}" = 'qa' ]; then
  logmessage "Running with QA settings"
elif [ "${ENVIRONMENT}" = 'prod' ]; then
  logmessage "Running with prod settings"
else
  printf '%s\n' "Environment is not valid. Please specify either QA or Prod" && exit 1
fi

check_logfile
make_git_bundle
encrypt_and_copy_bundle
