#!/bin/bash

NO_COLOR='\033[0m'
BLUE='\033[0;34m'
RED='\033[0;31m'

DEFAULT_STORAGE_SKU="Standard_LRS"
DEFAULT_PLAN="xdm-purview-connector-plan"
DEFAULT_PLAN_WORKERS=1
DEFAULT_PLAN_SKU="EP1"
DEFAULT_DOCKER_IMAGE="semarchy/xdm-purview-connector"
DEFAULT_DOCKER_IMAGE_TAG="2023.2.0"
DEFAULT_LOCATION=westeurope

SETTINGS_FILE_NAME=create-azure-function-app-settings.json
help()
{
    echo -e "Usage: $(basename "$0")
Arguments $BLUE'default value'$NO_COLOR
        --name -n              [Required] : Name of azure function app to deploy. Must be unique to Azure (used for REST endpoint URL: https//<name>.azurewebsites.net/api/)
        --storage-account -s   [Required] : Name of storage account to create/update (must be unique and contain 3 to 24 characters numbers and lowercase letters only).
        --resource-group -g    [Required] : Name of resource group. You can configure the default group using 'az configure --defaults group=<name>'.
        --storage-account-sku             : $BLUE'$DEFAULT_STORAGE_SKU'$NO_COLOR The storage account SKU. Allowed values: Premium_LRS, Premium_ZRS, Standard_GRS, Standard_GZRS, Standard_LRS, Standard_RAGRS, Standard_RAGZRS, Standard_ZRS.
        --premium-plan                    : $BLUE'$DEFAULT_PLAN'$NO_COLOR The name of the app service plan
        --premium-plan-workers            : $BLUE'$DEFAULT_PLAN_WORKERS'$NO_COLOR The number of workers for the app service plan. cf. https://learn.microsoft.com/en-us/azure/azure-functions/functions-premium-plan?tabs=portal#available-instance-skus
        --premium-plan-sku                : $BLUE'$DEFAULT_PLAN_SKU'$NO_COLOR The SKU of the app service premium plan. For a Docker Azure function: EP1, EP2 or EP3 are recommended.
        --docker-image                    : $BLUE'$DEFAULT_DOCKER_IMAGE'$NO_COLOR Name of docker image to deploy to azure function app
        --docker-image-tag                : $BLUE'$DEFAULT_DOCKER_IMAGE_TAG'$NO_COLOR Docker image tag
        --location -l                     : $BLUE'$DEFAULT_LOCATION'$NO_COLOR Location. Values from: 'az account list-locations'. You can configure the default location using 'az configure --defaults location=<location>'.
        --help -h                         : Show this help message and exit.

Example
  Create/Update an Azure function app with default parameters. Will create Storage Account and Resource Group if not found.
      $(basename "$0") --storage-account devpurviewstorageaccount --resource-group dev-purview-sandbox
"
    exit 2
}

error() {
  echo -e "${RED}$*${NO_COLOR}";
}

checkOk() {
  ret=$?
  if [ "$ret" != "0" ];then
    exit "$ret"
  fi
}

getJsonValue() {
  outputLine=$(echo "$1" | grep "$2")
  IFS='"' read -ra ADDR <<< "$outputLine"
  echo "${ADDR[3]}"
}

SHORT=n:,s:,g:,l:,h
LONG=name:,storage-account:,resource-group:,storage-account-sku:,premium-plan:,premium-plan-workers:,premium-plan-sku:,docker-image:,docker-image-tag:,location:,help
OPTS=$(getopt -a -n "$(basename "$0")" --options $SHORT --longoptions $LONG -- "$@")

VALID_ARGUMENTS=$# # Returns the count of arguments that are in short or long options

if [ "$VALID_ARGUMENTS" -eq 0 ]; then
  help
fi

eval set -- "$OPTS"

while :
do
  case "$1" in
    -n | --name)
      azureFunctionAppName="$2"
      shift 2
      ;;
    -s | --storage-account )
      storageAccount="$2"
      shift 2
      ;;
    -g | --resource-group)
      resourceGroup="$2"
      shift 2
      ;;
    --storage-account-sku )
      storageAccountSku="$2"
      shift 2
      ;;
    --premium-plan)
      premiumPlan="$2"
      shift 2
      ;;
    --premium-plan-workers)
      premiumPlanWorkers="$2"
      shift 2
      ;;
    --premium-plan-sku)
      premiumPlanSku="$2"
      shift 2
      ;;
    --docker-image)
      dockerImage="$2"
      shift 2
      ;;
    --docker-image-tag)
      dockerImageTag="$2"
      shift 2
      ;;
    -l | --location)
      location="$2"
      shift 2
      ;;
    -h | --help)
      help
      ;;
    --)
      shift;
      break
      ;;
    *)
      error "Unexpected option: $1"
      help
      ;;
  esac
done

if [ "$storageAccount" == "" ]; then
  error "argument missing: --storage-account"
  help
fi

if [ "$resourceGroup" == "" ]; then
  error "argument missing: --resource-group"
  help
fi

if [ "$azureFunctionAppName" == "" ]; then
  error "argument missing: --name"
  help
fi

if [ "$storageAccountSku" == "" ]; then
  storageAccountSku="$DEFAULT_STORAGE_SKU"
fi

if [ "$premiumPlan" == "" ]; then
  premiumPlan="$DEFAULT_PLAN"
fi

if [ "$premiumPlanWorkers" == "" ]; then
  premiumPlanWorkers="$DEFAULT_PLAN_WORKERS"
fi

if [ "$premiumPlanSku" == "" ]; then
  premiumPlanSku="$DEFAULT_PLAN_SKU"
fi

if [ "$premiumPlanSku" != "EP1" ] && [ "$premiumPlanSku" != "EP2" ] && [ "$premiumPlanSku" != "EP2" ]; then
  error "Premium plan '$premiumPlanSku' is unknown/not recommended."
fi

if [ "$dockerImage" == "" ]; then
  dockerImage="$DEFAULT_DOCKER_IMAGE"
fi

if [ "$dockerImageTag" == "" ]; then
  dockerImageTag="$DEFAULT_DOCKER_IMAGE_TAG"
fi

if [ "$location" == "" ]; then
  location="$DEFAULT_LOCATION"
fi

if ! az account show >/dev/null 2>&1; then
  az login
fi

if ! az group exists -g "$resourceGroup" >/dev/null 2>&1; then
  echo "-----------------------------------------------"
  echo "Creating Resource Group '$resourceGroup' ..."
  if ! az group create --location "$location" --resource-group "$resourceGroup"; then
    error "Failed to create Resource Group $resourceGroup. Please check Azure account privileges."
    exit 2
  fi
fi

echo "-----------------------------------------------"
echo "Creating/Updating Storage Account '$storageAccount' ..."
az storage account create \
                    --name "$storageAccount"\
                    --location "$location"\
                    --resource-group "$resourceGroup"\
                    --sku "$storageAccountSku"
checkOk

echo "-----------------------------------------------"
echo "Creating/Updating Premium plan '$premiumPlan' for Azure Functions App ..."
az functionapp plan create \
                    --resource-group "$resourceGroup"\
                    --name "$premiumPlan"\
                    --location "$location"\
                    --number-of-workers "$premiumPlanWorkers"\
                    --sku "$premiumPlanSku"\
                    --is-linux
checkOk

dockerImageWithTag="$dockerImage:$dockerImageTag"
echo "-----------------------------------------------"
echo "Creating/Updating Azure function app '$azureFunctionAppName' with image '$dockerImageWithTag' ..."
az functionapp create \
              --name "$azureFunctionAppName" \
              --storage-account "$storageAccount" \
              --resource-group "$resourceGroup" \
              --plan "$premiumPlan" \
              --deployment-container-image-name "$dockerImageWithTag" \
              --functions-version 3 \
              --runtime java
checkOk

storageAccountConnectionString=$(az storage account show-connection-string --name "$storageAccount" --resource-group "$resourceGroup" --query connectionString --output tsv)
az functionapp config appsettings set -g "$resourceGroup" -n "$azureFunctionAppName" --settings "AzureWebJobsStorage=$storageAccountConnectionString"
echo "-----------------------------------------------"
echo "Registered Storage Account Application Setting: AzureWebJobsStorage=$storageAccountConnectionString"

echo "-----------------------------------------------"
echo "Updating function app '$azureFunctionAppName' settings from $SETTINGS_FILE_NAME ..."
az functionapp config appsettings set -g "$resourceGroup" -n "$azureFunctionAppName" --settings @"$SETTINGS_FILE_NAME"

echo "-----------------------------------------------"
echo "Settings:"
cat "$SETTINGS_FILE_NAME"
