#!/bin/bash

GCE_STATE_DIR=/var/lib/gce-xfstests

if test -z "$MDS_PREFIX"
then
    declare -r MDS_PREFIX=http://metadata.google.internal/computeMetadata/v1
    declare -r MDS_TRIES=${MDS_TRIES:-100}
fi

function print_metadata_value() {
  local readonly tmpfile=$(mktemp)
  http_code=$(curl -f "${1}" -H "Metadata-Flavor: Google" -w "%{http_code}" \
    -s -o ${tmpfile} 2>/dev/null)
  local readonly return_code=$?
  # If the command completed successfully, print the metadata value to stdout.
  if [[ ${return_code} == 0 && ${http_code} == 200 ]]; then
    cat ${tmpfile}
  fi
  rm -f ${tmpfile}
  return ${return_code}
}

function print_metadata_value_if_exists() {
  local return_code=1
  local readonly url=$1
  print_metadata_value ${url}
  return_code=$?
  return ${return_code}
}

function get_metadata_value() {
  local readonly varname=$1
  # Print the instance metadata value.
  print_metadata_value_if_exists ${MDS_PREFIX}/instance/${varname}
  return_code=$?
  # If the instance doesn't have the value, try the project.
  if [[ ${return_code} != 0 ]]; then
    print_metadata_value_if_exists ${MDS_PREFIX}/project/${varname}
    return_code=$?
  fi
  return ${return_code}
}

function get_metadata_value_with_retries() {
  local return_code=1  # General error code.
  for ((count=0; count <= ${MDS_TRIES}; count++)); do
    get_metadata_value $1
    return_code=$?
    case $return_code in
      # No error.  We're done.
      0) return ${return_code};;
      # Failed to resolve host or connect to host.  Retry.
      6|7) sleep 0.3; continue;;
      # A genuine error.  Exit.
      *) return ${return_code};
    esac
  done
  # Exit with the last return code we got.
  return ${return_code}
}

function gce_attribute() {
	get_metadata_value_with_retries attributes/$1
}

GCE_CONFIG_FILE="/usr/local/lib/gce_xfstests.config"
if test -f "$GCE_CONFIG_FILE"
then
    . "$GCE_CONFIG_FILE"
fi

mkdir -p $GCE_STATE_DIR

if test -f $GCE_STATE_DIR/gce_zone
then
    ZONE=$(cat $GCE_STATE_DIR/gce_zone)
else
    ZONE=$(get_metadata_value_with_retries zone)
    ZONE=$(basename $ZONE)
    echo $ZONE > $GCE_STATE_DIR/gce_zone
fi
REGION=$(echo $ZONE | awk -F- '{printf("%s-%s",$1,$2)}')

if test -f $GCE_STATE_DIR/gce_id
then
    GCE_ID=$(cat $GCE_STATE_DIR/gce_id)
else
    GCE_ID=$(get_metadata_value_with_retries id)
    echo $GCE_ID > $GCE_STATE_DIR/gce_id
fi

if test -f $GCE_STATE_DIR/instance
then
    instance="$(cat $GCE_STATE_DIR/instance)"
else
    instance=$(get_metadata_value_with_retries name)
    echo "$instance" > "$GCE_STATE_DIR/instance"
fi

if test -f $GCE_STATE_DIR/testrunid
then
    TESTRUNID=$(cat $GCE_STATE_DIR/testrunid)
else
    case "$instance" in
	xfstests-*)
	    TESTRUNID=$(echo $instance | sed -e 's/xfstests-//')
	    ;;
	*)
	    TESTRUNID=$(date +%Y%m%d%H%M%S)
	    ;;
    esac
    echo $TESTRUNID > $GCE_STATE_DIR/testrunid
fi

if test -f $GCE_STATE_DIR/gs_bucket
then
    GS_BUCKET=$(cat $GCE_STATE_DIR/gs_bucket)
else
    GS_BUCKET=$(gce_attribute gs_bucket)
    echo $GS_BUCKET > $GCE_STATE_DIR/gs_bucket
fi

if test -f $GCE_STATE_DIR/bucket_subdir
then
    BUCKET_SUBDIR=$(cat $GCE_STATE_DIR/bucket_subdir)
else
    OVERRIDE_SUBDIR=$(gce_attribute bucket_subdir)
    # if the gce attribute exists, we use it to override the bucket_subdir value
    # in the config file. otherwise we keep the value in the config file.
    if test $?=0; then
	BUCKET_SUBDIR=$OVERRIDE_SUBDIR
    fi
    echo $BUCKET_SUBDIR > $GCE_STATE_DIR/bucket_subdir
fi

function run_hooks() {
    local hook=$1
    shift

    local HOOK_ARG="$*"
    export HOOK_ARG

    if test "$hook" != "logger"
    then
	logger gce-xfstests: checking for hook $hook
    fi
    if test -f /root/hooks/$hook.block
    then
	logger gce-xfstests: blocking on $hook
	while test -f /root/hooks/$hook.block
	do
	    sleep 1
	done
	logger gce-xfstests: done blocking on $hook
    fi
    if test -e /root/hooks/$hook
    then
	/root/hooks/$hook
    fi
    if test -f /root/hooks/$hook.sh
    then
	. /root/hooks/$hook.sh
    fi
    if test -d /root/hooks/$hook.d
    then
	run-parts /root/hooks/pre-setup.d
    fi
}
