#!/bin/bash

if ! [ -x "$(command -v jq)" ]; then
    echo "Installing jq..."
    echo
    sudo yum install -y jq > /dev/null
fi

print_dots () {
    local COUNTDOWN=$1
    if [ -z "$COUNTDOWN" ]; then
        COUNTDOWN=60
    fi
    while [ "$COUNTDOWN" -gt 0 ]; do
        echo -ne "."
        sleep 1
        let COUNTDOWN--
    done
    echo
}

AWS_REGION=$(aws configure list | grep region | awk '{print $2}')
CODEBUILD_PROJECT="saas-bootcamp-product-svc"
CODE_PIPELINE="saas-bootcamp-product-svc"
BOOTCAMP_BUCKET=$(aws ssm get-parameter --name "saas-bootcamp-bucket" | jq -r '.Parameter.Value')
BOOTCAMP_BUCKET_PREFIX=$(aws ssm get-parameter --name "saas-bootcamp-bucket-prefix" | jq -r '.Parameter.Value')
DEPLOY_MONITOR_QUEUE=$(aws ssm get-parameter --name "saas-bootcamp-ci-cd-queue" | jq -r '.Parameter.Value')

if [ -z "$BOOTCAMP_BUCKET" ]; then
    echo "Error: Can't determine SaaS Bootcamp S3 bucket name"
    exit 1
fi
if [ -z "$DEPLOY_MONITOR_QUEUE" ]; then
    echo "Error: Can't determine SaaS Bootcamp SQS queue URL"
    exit 1
fi

if [ "N/A" == "$BOOTCAMP_BUCKET_PREFIX" ]; then
    BOOTCAMP_BUCKET_PREFIX=""
fi

echo "SaaS Bootcamp S3 bucket: $BOOTCAMP_BUCKET"
echo "SaaS Bootcamp S3 bucket prefix: $BOOTCAMP_BUCKET_PREFIX"
echo "SaaS Bootcamp SQS queue: $DEPLOY_MONITOR_QUEUE"
echo

# Make sure the queue is empty before we start
aws sqs purge-queue --queue-url "$DEPLOY_MONITOR_QUEUE" > /dev/null

# Upload the updated code to S3
echo "Uploading code to S3"
aws s3 cp server.js s3://${BOOTCAMP_BUCKET}/${BOOTCAMP_BUCKET_PREFIX}source/product-manager/

# Trigger a new build to create a fresh docker image with the updated code
BUILD_PROJECT=$(aws codebuild start-build --project-name ${CODEBUILD_PROJECT})
BUILD_ID=$(echo $BUILD_PROJECT | jq -r '.build.id')

# Now, wait for CodePipeline to finish deploying everything to ECS
echo
echo "Rebuilding and deploying the Product Manager service. This can take a few minutes."
echo "You can view the details of the CI/CD process in the AWS console for CodeBuild and CodePipeline."
echo

# CodeBuild will take at least 1 minute
echo "Building a new docker image."
print_dots 60

BUILD_RUNNING=true
while [ "$BUILD_RUNNING" = true ]; do
    BUILD_PHASE=$(aws codebuild batch-get-builds --ids $BUILD_ID | jq -r '.builds[].currentPhase')
    if [ "$BUILD_PHASE" = "COMPLETED" ]; then
        BUILD_RUNNING=false
    else
        # After a minute, we'll check on the build every 5 seconds
        print_dots 5
    fi
done

echo
echo "Docker image built. Waiting for deployment to finish."

# CodePipeline will take 2+ minutes
LOOP=0
while true; do
    let LOOP++
    if [ "$LOOP" -gt 15 ]; then
        echo "This is taking too long. Please check the AWS CodePipeline console for unexpected errors."
        exit 1
    fi
    # Long poll SQS for 10 seconds
    SQS=$(aws sqs receive-message --queue-url "$DEPLOY_MONITOR_QUEUE" --wait-time-seconds 10 --max-number-of-messages 1)
    if ! [ -z "$SQS" ]; then
        #echo $SQS
        MESSAGE=$(echo $SQS | jq -r '.Messages[]')
        RECEIPT=$(echo $MESSAGE | jq -r '.ReceiptHandle')
        
        # Clean up SQS
        aws sqs delete-message --queue-url "$DEPLOY_MONITOR_QUEUE" --receipt-handle "$RECEIPT"
        echo
        echo "Deployment finished."
        exit
    else
        # The first couple of times pause for another minute before trying again
        # then check every 10 seconds
        if [ "$LOOP" -lt 3 ]; then
            print_dots 60
        else
            print_dots 10
        fi
    fi
done
