#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# GameLift configuration; see https://docs.aws.amazon.com/cli/latest/reference/gamelift/create-fleet.html
{
    AWS_REGION="${AWS_REGION:-us-west-2}"   # may be overridden by environment variable
    PROJECT_NAME="Phantom"
    FLEET_SIZE="1"
    FLEET_TYPE="SPOT" # or "ON_DEMAND"
    SESSION_PROTECTION="NoProtection" # or "FullProtection"
    APPS_PER_INSTANCE="4" # TODO: this was chosen arbitrarily; adjust based on your performance tests
    EC2_INSTANCE_TYPE="c4.large"
    BUILD_VERSION="0.0.1"
    DATESTAMP="$(date '+%Y-%m-%d_%H:%M:%S')"

    # Port ranges specified in SERVER_ACLS must match those specified in RUNTIME_CONFIGURATION
    SERVER_ACLS='['
    SERVER_ACLS+='{"FromPort":8192,"ToPort":9192,"IpRange":"0.0.0.0/0","Protocol":"TCP"}' # game server ports
    SERVER_ACLS+=','
    SERVER_ACLS+='{"FromPort":22,"ToPort":22,"IpRange":"0.0.0.0/0","Protocol":"TCP"}' # SSH for debugging
    SERVER_ACLS+=']'

    RUNTIME_CONFIGURATION="ServerProcesses="
    RUNTIME_CONFIGURATION+="[{"
    RUNTIME_CONFIGURATION+="LaunchPath=/local/game/run-server.sh"
    RUNTIME_CONFIGURATION+=",Parameters='--port=8192 --end=9192'"
    RUNTIME_CONFIGURATION+=",ConcurrentExecutions=$APPS_PER_INSTANCE"
    RUNTIME_CONFIGURATION+="}]"

    CREATION_LIMIT="NewGameSessionsPerCreator=5,PolicyPeriodInMinutes=1"
}

# Make the distribution directory
{
    BUILD_ROOT="$(realpath "$SCRIPT_DIR/../_dist")"
    rm "$BUILD_ROOT" -rf
    "$SCRIPT_DIR/make-dist"
}

# Upload the build
{
    BUILD_ID="$(
        aws gamelift upload-build                                   \
            --name "$(whoami)-$PROJECT_NAME-build-$DATESTAMP"       \
            --build-version "$BUILD_VERSION-$DATESTAMP"             \
            --build-root "$BUILD_ROOT"                              \
            --operating-system "AMAZON_LINUX"                       \
            --region "$AWS_REGION"                                  \
            | tail -1                                               \
            | cut -d ' ' -f 3                                       \
        #
    )"
    # Instead of "tail | cut", above, what we to do is shown below, but there is a bug in AWSCLI:
    # "aws gamelift upload-build" outputs progress to stdout and does not use AWSCLI global parameters
    #        --query "Build ID"                     \
    #        --output text                          \
    # This bug exists in aws-cli/1.16.38 and has been reported
    echo "BuildId: $BUILD_ID"
}

# Create a fleet
{
    FLEET_ID="$(
        aws gamelift create-fleet                                       \
            --name "$(whoami)-$PROJECT_NAME-fleet-$DATESTAMP"           \
            --description "$PROJECT_NAME fleet created by '$(whoami)'"  \
            --ec2-instance-type "$EC2_INSTANCE_TYPE"                    \
            --ec2-inbound-permissions "$SERVER_ACLS"                    \
            --new-game-session-protection-policy "$SESSION_PROTECTION"  \
            --resource-creation-limit-policy "$CREATION_LIMIT"          \
            --runtime-configuration "$RUNTIME_CONFIGURATION"            \
            --fleet-type "$FLEET_TYPE"                                  \
            --region "$AWS_REGION"                                      \
            --build-id "$BUILD_ID"                                      \
            --query "FleetAttributes.FleetId"                           \
            --output text                                               \
        #                                                                                                                                                   #
    )"
    echo "FleetId: $FLEET_ID"
}

# Set fleet capacity
{
    "$SCRIPT_DIR/set-gamelift-fleet-capacity" --region "$AWS_REGION" --fleet-id "$FLEET_ID" --capacity "$FLEET_SIZE" --max-capacity "$FLEET_SIZE"
}

# Wait until fleet capacity matches target
{
    "$SCRIPT_DIR/wait-gamelift-fleet-capacity" --region "$AWS_REGION" --fleet-id "$FLEET_ID" --capacity "$FLEET_SIZE"
}
