#!/bin/zsh -e
# Required versions of things.
required_terraform="0.11.1"
required_wtf="2.2.6"

argdir="$(dirname $0)/$1"

if [[ $# != 1 || ! -d "${argdir}" ]]
then
    echo "Usage: $0 [[account/region]]" >&2
    echo "Terraform account/regions require wtf >= ${required_wtf} and terraform >= ${required_terraform}" >&2
    echo "Awscli required for cloudformation account/regions" >&2
    exit 1
fi

# Parse account and region from the argument.
account=$(basename $(dirname $1))
region=$(basename $1)

# If landscape is installed, use it to format the terraform plan nicely.
has_landscape=""
if which landscape &>/dev/null
then
    has_landscape="| landscape"
fi

# Work out of the directory where the terraform/cloudformation parameters live.
cd "${argdir}"

# Run $@, redirect all output to a temp file.
# If the command fails, cat the temp file to stderr and exit.
# If the command succeeds, remove the file without printing anything.
function run_silently() {
    out=$(mktemp)
    trap "rm $out" EXIT
    if ! $@ &>${out}
    then
        cat ${out} >&2
        exit 1
    fi
}

# Check that the given version is at least as new as the required version.
# Arguments:
#  $1: required version
#  $2: given version
# Versions are assumed to be split by `.` and contain exactly 3 components. Comparison rules are whatever
# awk gives by default. With numerical input, 1.1.10 > 1.1.2. With non-numeric input, 1.1.10-rc3 < 1.1.2.
function check_version() {
    echo "$1\n$2" | awk -F. '
        { if (NF != 3) { exit 1 } }
        NR==1 { major=$1; minor=$2; patch=$3 }
        NR==2 {
            if ( $1 < major ) { exit 1 }
            if ( $1 == major && $2 < minor) { exit 1 }
            if ( $1 == major && $2 == minor && $3 < patch ) { exit 1 }
        }
    '
}

# Check wtf and terraform versions.
# Reads ${required_wtf} and ${required_terraform} variables.
function check_terraform() {
    wtf_version=$(wtf -v | head -1 | sed 's/Version //g')
    tf_version=$(terraform version | head -1 | sed 's/Terraform v//g')

    if ! check_version ${required_wtf} ${wtf_version}
    then
        echo "Found wtf=${wtf_version}, required=${required_wtf}. Please upgrade: https://wiki.twitch.com/display/ENG/WTF" >&2
        exit 1
    fi

    if ! check_version ${required_terraform} ${tf_version}
    then
        echo "Found terraform=${tf_version}, required=${required_terraform}. Please upgrade." >&2
        exit 1
    fi
}

# Check awscli version.
function check_aws() {
    if ! which aws &>/dev/null
    then
        echo "Please install awscli" >&2
        exit 1
    fi
}

# Run terraform changes.
# Reads ${account} and ${region} globals.
function run_terraform() {
    check_terraform
    run_silently wtf -p -X -a ${account}

    eval "terraform show tf_apply.tf_plan $has_landscape"

    read -q "?Apply this plan to ${account} in ${region} (y/N)? " || exit 1
    wtf -a ${account}
}

# Run cloudformation changes.
# Reads ${account} and ${region} globals.
function run_cloudformation() {
    check_aws
    export AWS_PROFILE=${account}
    export AWS_DEFAULT_REGION=${region}

    # We're in the directory with parameters.json
    template="file://../../templates/networking.yaml"
    stack_name="base-networking-cf"

    run_silently aws cloudformation validate-template --template-body ${template}
    if aws cloudformation describe-stacks --stack-name ${stack_name} &>/dev/null
    then
        op="update"
    else
        op="create"
    fi

    echo "Running ${op}-stack on ${stack_name} in ${account}/${region}."
    aws cloudformation ${op}-stack --stack-name ${stack_name} --template-body ${template} --parameters file://parameters.json
    echo "Waiting for completion"
    aws cloudformation wait stack-${op}-complete --stack-name ${stack_name}
}

if [[ -f main.tf ]]
then
    run_terraform
else
    run_cloudformation
fi
