#!/usr/bin/env bash

#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -e

BASE_DIR=$(pwd)

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  SCRIPTDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
SCRIPTDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

. ${SCRIPTDIR}/shared_utilities.sh
is_source_from_pr_testable "geode" "$(get_geode_pr_exclusion_dirs)" "$(get_geode_pr_exclusion_files)" || exit 0

INSTANCE_NAME="$(cat instance-data/instance-name)"
INSTANCE_ID="$(cat instance-data/instance-information | jq -r '.[].id')"
GCP_PROJECT="$(cat instance-data/project)"
INSTANCE_PRICING_JSON="$(gsutil cat gs://${GCP_PROJECT}-infra/pricing/instance_pricing.json)"
PERMITTED_ZONES=($(gcloud compute zones list --filter="name~'us-central.*'" --format=json | jq -r .[].name))

echo 'StrictHostKeyChecking no' >> /etc/ssh/ssh_config

# Ensure no existing instance with this name in any zone
for KILL_ZONE in $(echo ${PERMITTED_ZONES[*]}); do
  gcloud compute instances delete ${INSTANCE_NAME} --zone=${KILL_ZONE} --quiet &>/dev/null || true
done

while read BLAH ; do
    if [[ -z "${END_TIMESTAMP}" ]]; then
        END_TIMESTAMP=${BLAH}
    else
        START_TIMESTAMP=${BLAH}
    fi
done < <(gcloud logging read "resource.type=gce_instance AND resource.labels.instance_id=${INSTANCE_ID} AND logName=projects/${GCP_PROJECT}/logs/cloudaudit.googleapis.com%2Factivity" --format=json | jq -r '.[].timestamp')

START_SECONDS=$(date -d "${START_TIMESTAMP}" +%s)
END_SECONDS=$(date -d "${END_TIMESTAMP}" +%s)
TOTAL_SECONDS=$(expr ${END_SECONDS} - ${START_SECONDS})
FULL_MACHINE_TYPE="$(cat instance-data/instance-information | jq -r '.[].machineType')"
MACHINE_TYPE="${FULL_MACHINE_TYPE##*/}"

case "${MACHINE_TYPE}" in
  custom*)
    CPUS="$(echo "${MACHINE_TYPE}" | rev | cut -d'-' -f 2 | rev)"
    RAM_MB="$(echo "${MACHINE_TYPE}" | rev | cut -d'-' -f 1 | rev)"
    RAM="$(expr ${RAM_MB} / 1024)"
    MACHINE_FAMILY="n1"
    CPU_COST="$(echo "${INSTANCE_PRICING_JSON}" | jq -r ".\"${MACHINE_FAMILY}\".custom.cpu")"
    RAM_COST="$(echo "${INSTANCE_PRICING_JSON}" | jq -r ".\"${MACHINE_FAMILY}\".custom.ram")"
    ;;
  *-custom*)
    CPUS="$(echo "${MACHINE_TYPE}" | rev | cut -d'-' -f 2 | rev)"
    RAM_MB="$(echo "${MACHINE_TYPE}" | rev | cut -d'-' -f 1 | rev)"
    RAM="$(expr ${RAM_MB} / 1024)"
    MACHINE_FAMILY="$(echo "${MACHINE_TYPE}" | cut -d'-' -f 1)"
    CPU_COST="$(echo "${INSTANCE_PRICING_JSON}" | jq -r ".\"${MACHINE_FAMILY}\".custom.cpu")"
    RAM_COST="$(echo "${INSTANCE_PRICING_JSON}" | jq -r ".\"${MACHINE_FAMILY}\".custom.ram")"
    ;;
  *-standard*)
    CPUS="$(echo "${MACHINE_TYPE}" | rev | cut -d'-' -f 1 | rev)"
    RAM=$(expr ${CPUS} \* 4 )
    MACHINE_FAMILY="$(echo "${MACHINE_TYPE}" | cut -d'-' -f 1)"
    CPU_COST="$(echo "${INSTANCE_PRICING_JSON}" | jq -r ".\"${MACHINE_FAMILY}\".predefined.cpu")"
    RAM_COST="$(echo "${INSTANCE_PRICING_JSON}" | jq -r ".\"${MACHINE_FAMILY}\".predefined.ram")"
    ;;
  *-highcpu*)
    CPUS="$(echo "${MACHINE_TYPE}" | rev | cut -d'-' -f 1 | rev)"
    RAM=${CPUS}
    MACHINE_FAMILY="$(echo "${MACHINE_TYPE}" | cut -d'-' -f 1)"
    CPU_COST="$(echo "${INSTANCE_PRICING_JSON}" | jq -r ".\"${MACHINE_FAMILY}\".predefined.cpu")"
    RAM_COST="$(echo "${INSTANCE_PRICING_JSON}" | jq -r ".\"${MACHINE_FAMILY}\".predefined.ram")"
    ;;
  *)
    CPUS=0
    RAM=0
    MACHINE_FAMILY="unknown"
    CPU_COST=0
    RAM_COST=0
    ;;
esac

BUILD_NUMBER="$(cat instance-data/instance-information | jq -r '.[].labels."build-name"')"
JOB_NAME="$(cat instance-data/instance-information | jq -r '.[].labels."job-name"')"
PIPELINE_NAME="$(cat instance-data/instance-information | jq -r '.[].labels."pipeline-name"')"
TOTAL_COST=$(echo "scale = 6; ((${CPUS} * ${CPU_COST}) + (${RAM} * ${RAM_COST})) * ${TOTAL_SECONDS} / 3600" | bc)
echo "Total heavy lifter cost for ${PIPELINE_NAME}/${JOB_NAME} #${BUILD_NUMBER}: $ ${TOTAL_COST}"
cat <<EOF > instance-data/cost-data.json
{
  "pipeline": "${PIPELINE_NAME}",
  "job": "${JOB_NAME}",
  "instanceName": "${INSTANCE_NAME}",
  "instanceId": "${INSTANCE_ID}",
  "machineType": "${MACHINE_TYPE}",
  "cpu": "${CPUS}",
  "ram": "${RAM}",
  "seconds": "${TOTAL_SECONDS}",
  "cpuRate": "${CPU_COST}",
  "ramRate": "${RAM_COST}",
  "totalCost": "${TOTAL_COST}",
}
EOF
gsutil cp instance-data/cost-data.json gs://${GCP_PROJECT}-infra/costs/${PIPELINE_NAME}/${JOB_NAME}/${PIPELINE_NAME}-${JOB_NAME}-${BUILD_NUMBER}-${INSTANCE_ID}.json
