#!/bin/bash

## to round float with printf
export LC_NUMERIC=C

# This is the working directory
outputFolder=./greenspector

# This is used if you DO NOT provide a "-v" flag for version
DEFAULT_VERSION=$(date '+%d-%m-%Y %H:%M:%S')

# By default the script wait the measurement to complete test end 3600 seconds (1 hour)
DEFAULT_TIME_WAIT=3600

# The pipeline will fail if the Ecoscore is less than $ECOSCORE_LIMIT. Set to 0 if you do no want to verify the Ecoscore.
ECOSCORE_LIMIT=50


##########################################################################################
## This method displayEcoscore is called after the measurement to check Ecoscore
## You can add code to use this Ecoscore. Send to your own dashboard for example
##########################################################################################

displayEcoscore() {
  RESULT_FILE="$outputFolder/ecoscore.json"

  HTTP_CODE=$(curl -s -w "%{http_code}" -X 'GET' \
    "$STUDIO_URL/api/v1/versions/${VERSION_ANALYSE_ID}/ecoscores" \
    -H 'accept: application/json' \
    -H "Authorization: Bearer ${TOKEN_API}" \
    -o $RESULT_FILE)

  ecoscore=$(cat  ${RESULT_FILE} | jq -rc '.functional.global.global')
  scoreDisplayTime=$(cat  ${RESULT_FILE} | jq -rc '.functional.global.score["TT_PL"]')
  scoreEnergy=$(cat  ${RESULT_FILE} | jq -rc '.functional.global.score["AH_PL/s"]')
  scoreDataNetwork=$(cat  ${RESULT_FILE} | jq -rc '.functional.global.score["D_ID"]')

  ECOSCORE=$(printf "%.0f" $ecoscore)
  SCORE_DISPLAY_TIME=$(printf "%.0f" $scoreDisplayTime)
  SCORE_ENERGY=$(printf "%.0f" $scoreEnergy)
  SCORE_DATA_NETWORK=$(printf "%.0f" $scoreDataNetwork)
  
  echo "the ecoscore of the new version is $ECOSCORE"
  echo "the score for display time is $SCORE_DISPLAY_TIME"
  echo "the score for energy is $SCORE_ENERGY"
  echo "the score for data network is $SCORE_DATA_NETWORK"

  if (($ECOSCORE < $ECOSCORE_LIMIT)); then
    echo "ERROR: Eco score is less than $ECOSCORE_LIMIT: $ECOSCORE"
    exit 5
  fi

  echo "SUCCESS: Eco score is greater than $ECOSCORE_LIMIT: $ECOSCORE"
}
##########################################################################################

##########################################################################################
# This bloc is for all other methods used in this script                   
# Please do not touch this bloc                                        
##########################################################################################

declare -A MAP_EXTRAS

checkParameters() {
  if [ -z "$TOKEN_API" ]; then
    echo "Please provide an api token with the -t flag."
    exit 1
  fi

  if [ -z "$APPLICATION_ID" ]; then
    echo "Please provide the application id with the -a flag."
    exit 1
  fi

  if [ -z "$MONITORED_PACKAGE" ]; then
    echo "Please provide a package name to monitor with the -m flag."
    exit 1
  fi

  STUDIO_URL=${STUDIO_URL:-"https://saas.greenspector.com"}
  CORE_SERVER_URL=${CORE_SERVER_URL:-"https://core-saas-prod.greenspector.com"}
  ITERATIONS=${ITERATIONS:-1}
  VERSION=${VERSION:-$DEFAULT_VERSION}
  SCRIPT_FILE=${SCRIPT_FILE:-"script.testgb"}
  DEVICE_NAME=${DEVICE_NAME:-"Samsung - Galaxy S10"}
  OS=${OS:-"android"}
  SDK_VERSION=${SDK_VERSION:-"12"}

  if [ ! -f "${SCRIPT_FILE}" ]; then
    echo "Please provide the file ${SCRIPT_FILE} in the current directory"
    exit 1
  fi

  APP_TO_INSTALL=""
  if [[ -n "$URL_PACKAGE_TO_INSTALL" && "${URL_PACKAGE_TO_INSTALL}" != "http"* ]] ; then
    if [[ "${URL_PACKAGE_TO_INSTALL}" == *".apk" || "${URL_PACKAGE_TO_INSTALL}" == *"ipa" ]] ; then
      if [ ! -f "${URL_PACKAGE_TO_INSTALL}" ]; then
        echo "Please provide the file ${URL_PACKAGE_TO_INSTALL} in the current directory"
        exit 1
      fi
      APP_TO_INSTALL="-F app=@./${URL_PACKAGE_TO_INSTALL}"
    fi
  fi

  PROXY_DATA=""
  if [ ! -z "$PROXY_URL" ]; then
    PROXY_DATA="-x $PROXY_URL"
    if [ ! -z "$PROXY_LOGIN" ] && [ ! -z "$PROXY_PASSWORD" ] ; then
        PROXY_DATA="$PROXY_DATA -U $PROXY_LOGIN:$PROXY_PASSWORD"
        echo "Curl request will use a proxy with authentication"
    else
      echo "Curl request will use a proxy without authentication"
    fi
  else
    echo "Curl request will not use any proxy. No proxy configuration is set"
  fi
   
  if [ ! -z "$EXTRAS" ]; then
    # Utilise jq pour extraire chaque paire clé/valeur
    while IFS='=' read -r key value; do
        # Supprime les guillemets autour de la valeur
        value="${value//\"}"
        MAP_EXTRAS["$key"]="$value"
    done < <(echo "$EXTRAS" | jq -r 'to_entries[] | "\(.key)=\(.value)"')
  fi
}

checkError() {
  if [ "$HTTP_CODE" != "200" ]; then
    echo "Error: the request ended with the http code $HTTP_CODE"
    exit 2
  fi
}

getTokenCoreServer() {
  RESULT_FILE="$outputFolder/coreServerToken.json"

  HTTP_CODE=$(curl -s -w "%{http_code}" -X 'GET' \
    "$STUDIO_URL/api/v1/user/greenspectortoken" \
    -H 'accept: application/json' \
    -H "Authorization: Bearer ${TOKEN_API}" \
    -o $RESULT_FILE)

  checkError

  TOKEN_CORE_SERVER=$(cat  ${RESULT_FILE} | jq -rc '.greenspectorToken') 
}

createNewVersion() {
  RESULT_FILE="$outputFolder/createVersionResponse.json"

  HTTP_CODE=$(curl -s -w "%{http_code}" -X 'POST' \
    "$STUDIO_URL/api/v1/applications/${APPLICATION_ID}/versions" \
    -H 'accept: application/json' \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer ${TOKEN_API}" \
    --data "$(jq -n --arg var "${VERSION}"  '.version = $var')" \
    -o $RESULT_FILE)

  checkError

  VERSION_ANALYSE_ID=$(cat  ${RESULT_FILE} | jq -rc '._id') 
}

getApplicationNameOnCoreServer() {
  RESULT_FILE="$outputFolder/coreServerInformations.json"
  
  HTTP_CODE=$(curl -s -w "%{http_code}" -X 'GET' \
    "$STUDIO_URL/api/v1/applications/${APPLICATION_ID}/parts" \
    -H 'accept: application/json' \
    -H "Authorization: Bearer ${TOKEN_API}" \
    -o $RESULT_FILE)

  checkError

  APPLICATION_NAME_CORE_SERVER=$(cat  ${RESULT_FILE} | jq -rc '.[0].name') 
}

launchMeasurement() {
  JOB_JSON="$outputFolder/job.json"

  echo '{
    "application": "testbench custom-apk",
    "version": "1.0",
    "environment": {
      "platform": "mobile",
      "device": "Samsung - Galaxy S10",
      "os": "android",
      "version": "12"
    },
    "job": {
      "iterations": 1,
      "apps": [],
      "monitoredPackage": "com.android.chrome",
      "testssuites": [
        {
            "name": "launch",
            "testfiles": [
                "script.testgb"
            ]
        }
      ],
      "extras": {
        "PAUSEDURATION": "30000",
        "PAUSEAFTERLOAD": "1000"
      }
    }}' > $JOB_JSON

  contents="$(jq --arg app "$APPLICATION_NAME_CORE_SERVER" '.application = $app' $JOB_JSON)" && echo "${contents}" > $JOB_JSON
  contents="$(jq --arg version "$VERSION" '.version = $version' $JOB_JSON)" && echo "${contents}" > $JOB_JSON
  contents="$(jq --arg device "$DEVICE_NAME" '.environment.device = $device' $JOB_JSON)" && echo "${contents}" > $JOB_JSON
  contents="$(jq --arg os "$OS" '.environment.os = $os' $JOB_JSON)" && echo "${contents}" > $JOB_JSON
  contents="$(jq --arg sdkVersion "$SDK_VERSION" '.environment.version = $sdkVersion' $JOB_JSON)" && echo "${contents}" > $JOB_JSON
  contents="$(jq --arg monitoredPackage "$MONITORED_PACKAGE" '.job.monitoredPackage = $monitoredPackage' $JOB_JSON)" && echo "${contents}" > $JOB_JSON
  contents="$(jq --argjson iterations $ITERATIONS '.job.iterations = $iterations' $JOB_JSON)" && echo "${contents}" > $JOB_JSON
  contents="$(jq --arg scriptFile "$SCRIPT_FILE" '.job.testssuites[0].testfiles[0] = $scriptFile' $JOB_JSON)" && echo "${contents}" > $JOB_JSON
  
  if [ -n "$URL_PACKAGE_TO_INSTALL" ]; then
    contents="$(jq --arg appToInstall "$URL_PACKAGE_TO_INSTALL" '.job.apps[0] = $appToInstall' $JOB_JSON)" && echo "${contents}" > $JOB_JSON
  fi
  
  # set extras
  for key in "${!MAP_EXTRAS[@]}"; do
      value=${MAP_EXTRAS[$key]}
      newEntry="{\"$key\":\"$value\"}"
      contents="$(jq --argjson extra "$newEntry" --arg value1 "value1" '.job.extras += $extra' $JOB_JSON)" && echo "${contents}" > $JOB_JSON
  done

  # echo $contents


  JOB_LAUNCH="$outputFolder/job_launch.json"
  
  # launch a measurement on core server
  HTTP_CODE=$(curl -s -w "%{http_code}" -X 'POST' \
  $CORE_SERVER_URL/api/testbench/jobs/custom \
  $PROXY_DATA \
  -H "PRIVATE-TOKEN: $TOKEN_CORE_SERVER" \
  -F data="$(cat $JOB_JSON)" \
  -F dsl=@./"$SCRIPT_FILE" \
  $APP_TO_INSTALL \
  -o $JOB_LAUNCH)

  checkError
}

waitForMeasurementEnd() {
  RESULT_FILE="$outputFolder/status.json"
  echo "wait for measurement end"

  iterationTimeout=$(($DEFAULT_TIME_WAIT / 10))
  itTimeout=$(printf "%.0f\n" $iterationTimeout)

  for i in {1..10}
  do
    printf "read version status $i times\n"
    rm -rf $RESULT_FILE

    HTTP_CODE=$(curl -s -w "%{http_code}" -X 'GET' \
      "$STUDIO_URL/api/v1/versions/${VERSION_ANALYSE_ID}/status" \
      -H 'accept: application/json' \
      -H "Authorization: Bearer ${TOKEN_API}" \
      -o $RESULT_FILE)

      checkError

      STATUS_CODE=$(cat  ${RESULT_FILE} | jq -rc '.[0].statusCode')

    if [ "$STATUS_CODE" != "0" ]; then
        break
    fi
    sleep $itTimeout
  done
}

handleStatusCode() {
  if [ "$STATUS_CODE" == "0" ]; then
    echo "The measurement does not end in time"
    exit 3
  elif [ "$STATUS_CODE" == "6" ]; then
    echo "The measurement is complete"
  else 
    echo "The measurement has some problems. Can't diplay ecoscore."
    exit 4
  fi
}
##########################################################################################

##########################################################################################
# Main part of the script                                                    
#                                                                            
##########################################################################################

## options for the script
while getopts a:t:m:i:v:d:o:k:f:u:s:c:r:l:p:e: flag; do
    case "${flag}" in
    a) APPLICATION_ID=${OPTARG} ;;
    t) TOKEN_API=${OPTARG} ;;
    m) MONITORED_PACKAGE=${OPTARG} ;;
    i) ITERATIONS=${OPTARG} ;;
    v) VERSION=${OPTARG} ;;
    d) DEVICE_NAME=${OPTARG} ;;
    o) OS=${OPTARG} ;;
    k) SDK_VERSION=${OPTARG} ;;
    f) SCRIPT_FILE=${OPTARG} ;;
    u) URL_PACKAGE_TO_INSTALL=${OPTARG} ;;
    s) STUDIO_URL=${OPTARG} ;;
    c) CORE_SERVER_URL=${OPTARG} ;;
    r) PROXY_URL=${OPTARG} ;;
    l) PROXY_LOGIN=${OPTARG} ;;
    p) PROXY_PASSWORD=${OPTARG} ;;
    e) EXTRAS=${OPTARG} ;;
    esac
  done

checkParameters

APPLICATION_NAME_CORE_SERVER=""
TOKEN_CORE_SERVER=""
VERSION_ANALYSE_ID=""

# clean previous working directory
rm -rf $outputFolder
mkdir $outputFolder

getTokenCoreServer
echo "get token core server: $TOKEN_CORE_SERVER"

createNewVersion
echo "the new version $VERSION_ANALYSE_ID has been created"

getApplicationNameOnCoreServer 
echo "application name on core server is $APPLICATION_NAME_CORE_SERVER"

echo "launch measurement on core server"
launchMeasurement

echo "Wait for the end of the measurement (timeout $DEFAULT_TIME_WAIT seconds)"
waitForMeasurementEnd

echo "Handle version status code. Analyse if version is ok"
handleStatusCode

echo "Display Ecoscore"
displayEcoscore

##########################################################################################
