#!/usr/bin/env bash

set -e

usage() {
  cat <<EOF >&2
USAGE:
    $0 <BENCHMARK_FILEPATH>

REQUIRED ENVIRONMENTS:
    INFLUX_HOST           Hostname or IP address of the InfluxDB server
    INFLUX_DB             Name of the InfluxDB database
    INFLUX_USER           Username for InfluxDB
    INFLUX_PASSWORD       Password for InfluxDB
    INFLUX_MEASUREMENT    Measurement for InfluxDB

OPTIONAL ENVIRONMENTS:
    COMMIT_HASH   Commit hash of the benchmark file
    TEST_SUITE    The group name for all tests in the benchmark file
    DRY_RUN       Dry run

ARGS:
    <BENCHMARK_FILEPATH>    The output file generated by running
                            \`cargo bench -- -Z unstable-options --format=json\`
                            contains the benchmark results in JSON format
EOF
}

print_error_and_exit() {
  local msg="$1"
  echo "error: $msg" >&2
  echo ""
  usage
  exit 1
}

check_env() {
  local var_name="$1"
  if [ -z "${!var_name}" ]; then
    print_error_and_exit "Environment variable $var_name is required"
  fi
}

filepath="$1"
if [ ! -f "$filepath" ]; then
  print_error_and_exit "invalid <BENCHMARK_FILEPATH>"
fi

if [ -z "$COMMIT_HASH" ]; then
  COMMIT_HASH=$(uuidgen)
fi

if [ -z "$TEST_SUITE" ]; then
  TEST_SUITE="$(basename "${BENCHMARK_FILEPATH}")-$(date +%s)"
fi

if [ -z "$DRY_RUN" ]; then
  required_env_vars=(
    "INFLUX_HOST"
    "INFLUX_DB"
    "INFLUX_USER"
    "INFLUX_PASSWORD"
    "INFLUX_MEASUREMENT"
  )
  for var in "${required_env_vars[@]}"; do
    check_env "$var"
  done
fi

while IFS= read -r line; do

  if [[ $line =~ ^test\ (.*)\ \.\.\.\ bench:\ *([0-9,\.]+)\ ns\/iter\ \(\+\/-\ *([0-9,\.]+)\) ]]; then
    test_name="${BASH_REMATCH[1]}"
    ns_iter="${BASH_REMATCH[2]}"
    plus_minus="${BASH_REMATCH[3]}"

    ns_iter=$(echo "$ns_iter" | tr -d ',' | cut -d'.' -f1)
    plus_minus=$(echo "$plus_minus" | tr -d ',' | cut -d'.' -f1)

    datapoint="${INFLUX_MEASUREMENT},commit=${COMMIT_HASH},test_suite=${TEST_SUITE},name=${test_name} median=${ns_iter}i,deviation=${plus_minus}i"
    echo "datapoint: $datapoint"

    if [[ -z "$DRY_RUN" ]]; then
      curl -s -X POST "${INFLUX_HOST}/write?db=${INFLUX_DB}" --data-binary "$datapoint"
    fi
  fi

done <"$filepath"
