#!/bin/bash

set -euEo pipefail

# Setting +x to hide any provided USERNAME/PASSWORD data from the output
set +x

ASPEN_MESH_RELEASE_TYPE=${ASPEN_MESH_RELEASE_TYPE:-enterprise}
ASPEN_MESH_USERNAME=${ASPEN_MESH_USERNAME:-}
ASPEN_MESH_PASSWORD=${ASPEN_MESH_PASSWORD:-}
ASPEN_MESH_VERSION=${ASPEN_MESH_VERSION:-}

DOWNLOAD_HOST=${DOWNLOAD_HOST:-https://my.aspenmesh.io}
USER_POOL_REGION=${USER_POOL_REGION:-us-east-1}
CLIENT_ID=${CLIENT_ID:-75pv0l4jijmff7qefnhtfg66s2}

function check-cmd {
  CMD=$1

  command -v "$CMD" >/dev/null 2>&1 || {
    echo >&2 "Could not find $CMD. Please install it."
    exit 1
  }
}

check-cmd curl
check-cmd jq
check-cmd base64

if [ -z "$ASPEN_MESH_USERNAME" ]; then
  echo -n "Enter your Aspen Mesh username: "
  read -r ASPEN_MESH_USERNAME
fi

if [ -z "$ASPEN_MESH_PASSWORD" ]; then
  stty -echo
  echo -n "Enter your Aspen Mesh password: "
  read -r ASPEN_MESH_PASSWORD
  stty echo
  echo
fi

if ! COGNITO_OUT=$(curl --request POST https://cognito-idp."$USER_POOL_REGION".amazonaws.com/ \
    --silent --fail \
    --header "X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth" \
    --header "Content-Type: application/x-amz-json-1.1" \
    --data '{
      "ClientMetadata": {},
      "AuthParameters": {
        "USERNAME": "'"$ASPEN_MESH_USERNAME"'",
        "PASSWORD": "'"$ASPEN_MESH_PASSWORD"'"
      },
      "AuthFlow": "USER_PASSWORD_AUTH",
      "ClientId": "'"$CLIENT_ID"'"
    }'); then
  echo >&2 "Failed to log in to Aspen Mesh. Check your username and password."
  exit 1
fi

BASE64_OPTS=""
if [ "$(uname)" == "Linux" ]; then
  BASE64_OPTS="--wrap=0"
fi

TOKEN=$(echo "$COGNITO_OUT" |
  jq -c ".AuthenticationResult | {access: .AccessToken, id: .IdToken}" - |
  base64 $BASE64_OPTS
)

ID_TOKEN=$(echo "$COGNITO_OUT" |
  jq -r -c ".AuthenticationResult.IdToken"
)
ACCESS_TOKEN=$(echo "$COGNITO_OUT" |
  jq -r -c ".AuthenticationResult.AccessToken"
)
REFRESH_TOKEN=$(echo "$COGNITO_OUT" |
  jq -r -c ".AuthenticationResult.RefreshToken"
)

if [ -z "$ASPEN_MESH_VERSION" ]; then
  echo -n "Enter the version of the Aspen Mesh release to download (e.g.: 1.9.8-am1): "
  read -r ASPEN_MESH_VERSION
fi

REL_TYPE=""
if [ "$ASPEN_MESH_RELEASE_TYPE" != "enterprise" ]; then
  REL_TYPE="-$ASPEN_MESH_RELEASE_TYPE"
fi

FILE="aspenmesh$REL_TYPE-$ASPEN_MESH_VERSION"
case $(uname | tr "[:upper:]" "[:lower:]") in
  linux*)
    FILE="$FILE-linux.tar.gz"
    ;;
  darwin*)
    FILE="$FILE-osx.tar.gz"
    ;;
  msys*)
    FILE="$FILE-win.zip"
    ;;
  *)
    echo >&2 "Operating system not recognized."
    exit 1
    ;;
esac

# Once /parseauth uri exists in the system we need to use the new cookie format, otherwise use the old format.
if curl --output /dev/null --silent --head --fail "$DOWNLOAD_HOST/parseauth"; then
  curl --fail \
    --cookie "ACCESS-TOKEN=$ACCESS_TOKEN;ID-TOKEN=$ID_TOKEN;REFRESH-TOKEN=$REFRESH_TOKEN;COGNITO-ENABLED=True" \
    --output "$FILE" \
    "$DOWNLOAD_HOST/client/release/$ASPEN_MESH_VERSION/$FILE"
else
  curl --fail --header "Authorization: Bearer $TOKEN" --output "$FILE" \
      "$DOWNLOAD_HOST/client/release/$ASPEN_MESH_VERSION/$FILE"
fi
