#!/bin/bash

set -e -u

(
echo Inputs
echo BROKER_URI: ${BROKER_URI:?required}
echo ETCD_URI: ${ETCD_URI:?required}
echo EXPECTED_ETCD_HOST: ${EXPECTED_ETCD_HOST:?required}

# config
export timeout=${timeout:-3}

echo Target etcd version
curl ${ETCD_URI}/version
echo; echo

catalog=$(curl -m${timeout} -s ${BROKER_URI:?required}/v2/catalog)
service_id=$(echo $catalog | jq -r ".services[0].id")
plan_id=$(echo $catalog | jq -r ".services[0].plans[0].id")

instance_id=etcd-$(date +"%s" | rev)
binding_id=bind-$(date +"%s" | rev)

info() {
  echo "$@ " >&2
}

create_instance() {
  set +x
  info creating service instance ${instance_id} for plan ${plan_id}
  set -x
  curl ${BROKER_URI}/v2/service_instances/${instance_id} \
      -XPUT \
      -m${timeout} \
      -d "{\"service_id\":\"${service_id}\",\"plan_id\":\"${plan_id}\"}" \
      >&2 || {
    echo "Couldn't create service instance"
    exit 1
  }
}

create_binding() {
  set +x
  info creating binding ${binding_id} for instance ${instance_id}
  set -x
  curl -sf ${BROKER_URI}/v2/service_instances/${instance_id}/service_bindings/${binding_id} \
    -XPUT \
    -m${timeout} \
    -d "{\"service_id\": \"${service_id}\", \"plan_id\": \"${plan_id}\"}" || {
    echo "Couldn't create instance binding"
    exit 1
  }
}

delete_binding() {
  set +x
  info deleting binding ${binding_id} for instance ${instance_id}
  set -x
  curl -f -XDELETE -m${timeout} \
    ${BROKER_URI}/v2/service_instances/${instance_id}/service_bindings/${binding_id}\?service_id=${service_id}\&plan_id=${plan_id} || {
    echo "Couldn't delete instance binding"
    exit 1
  }
  set +x
}

delete_instance() {
  set +x
  info deleting instance ${instance_id}
  set -x
  curl -f -XDELETE -m${timeout} \
    ${BROKER_URI}/v2/service_instances/${instance_id}\?service_id=${service_id}\&plan_id=${plan_id} || {
    echo "Couldn't delete instance"
    exit 1
  }
  set +x
}

create_instance
credentials=$(create_binding)
set +x

echo Inspect users
curl  -m${timeout} -s ${ETCD_URI:?required}/v2/auth/users | jq .
curl  -m${timeout} -s ${ETCD_URI:?required}/v2/auth/users/user-${binding_id} | jq .
echo Inspect roles
curl  -m${timeout} -s ${ETCD_URI:?required}/v2/auth/roles | jq .
curl  -m${timeout} -s ${ETCD_URI:?required}/v2/auth/roles/instance-${instance_id} | jq .

echo $credentials | jq -r .

errors=
uri=$(echo $credentials | jq -r ".credentials.uri")
if [[ "${uri}X" == "X" || "${uri}" == "null" ]]; then
  echo "Binding credentials missing 'uri' key"
  errors=1
fi
keypath=$(echo $credentials | jq -r ".credentials.keypath")
if [[ "${keypath}X" == "X" || "${keypath}" == "null" ]]; then
  echo "Binding credentials missing 'keypath' key"
  errors=1
fi
password=$(echo $credentials | jq -r ".credentials.password")
if [[ "${password}X" == "X" || "${password}" == "null" ]]; then
  echo "Binding credentials missing 'password' key"
  errors=1
fi
username=$(echo $credentials | jq -r ".credentials.username")
if [[ "${username}X" == "X" || "${username}" == "null" ]]; then
  echo "Binding credentials missing 'username' key"
  errors=1
fi
host=$(echo $credentials | jq -r ".credentials.host")
if [[ "${host}X" == "X" || "${host}" == "null" ]]; then
  echo "Binding credentials missing 'host' key"
  errors=1
fi

if [[ "${EXPECTED_ETCD_HOST}" != "${host}" ]]; then
  echo "Expected host '$EXPECTED_ETCD_HOST' different from .credentials.host '${host}'"
  errors=1
fi

if [[ "$errors" == "1" ]]; then
  echo "Exiting due to preceding errors"
  exit 1
fi

echo Setting value
echo curl -m${timeout} $uri/v2/keys${keypath}/hello -XPUT -d 'value=world'
curl -m${timeout} $uri/v2/keys${keypath}/hello -XPUT -d 'value=world'

echo Getting value
echo curl -m${timeout} $uri/v2/keys${keypath}/hello
curl -m${timeout} $uri/v2/keys${keypath}/hello
value=$(curl -s -m${timeout} $uri/v2/keys${keypath}/hello | jq -r .node.value)
if [[ "${value}" != "world" ]]; then
  echo "Value retrived from $uri/hello should be 'world', was '${value}'"
  exit 1
fi

echo Setting to /not-allowed should not be allowed
echo curl ${uri}/v2/keys/not-allowed -XPUT -d 'value=try-this'
curl ${uri}/v2/keys/not-allowed -XPUT -d 'value=try-this'
if [[ "${ETCD_VERSION:-2.3}" != "2.2" ]]; then
  error_code=$(curl -s ${uri}/v2/keys/not-allowed -XPUT -d 'value=try-this' | jq -r .errorCode)
  if [[ "${error_code}" != "110" ]]; then
    echo "Expected errorCode 110 as shouldn't be allowed to access /not-allowed; got '${error_code}'"
    exit 1
  fi
  echo "Confirming that /not_allowed was not modified by user"
  not_allowed=$(curl -s ${ETCD_URI:?required}/v2/keys/not-allowed | jq -r .node.value)
  if [[ "${not_allowed}" != "null" ]]; then
    echo "Should not have allowed /not_allowed to be set"
    exit 1
  fi
fi

delete_binding
set +x
echo "access to /hello should now be denied"

curl $uri/v2/keys${keypath}/hello
if [[ "${ETCD_VERSION:-2.3}" != "2.2" ]]; then
  error_code=$(curl -s $uri/v2/keys${keypath}/hello | jq -r .errorCode)
  if [[ "${error_code}" != "110" ]]; then
    echo "Expected errorCode 110 as shouldn't be allowed to access /hello anymore; got '${error_code}'"
    exit 1
  fi
fi

echo "creating new binding, with same binding ID"
old_password=$password
old_keypath=$keypath
credentials=$(create_binding)
echo $credentials | jq -r .

uri=$(echo $credentials | jq -r ".credentials.uri")
if [[ "${uri}X" == "X" || "${uri}" == "null" ]]; then
  echo "Binding credentials missing 'uri' key"
  exit 1
fi

password=$(echo $credentials | jq -r ".credentials.password")
if [[ "${password}" == "${old_password}" ]]; then
  echo "Expecting new binding to have new password"
  exit 1
fi
keypath=$(echo $credentials | jq -r ".credentials.keypath")
if [[ "${keypath}" != "${old_keypath}" ]]; then
  echo "Expecting new binding to have same password; was '${old_keypath}', now '${keypath}'"
  exit 1
fi

echo "Getting value /hello again"
curl -s $uri/v2/keys${keypath}/hello
value=$(curl -s curl -s $uri/v2/keys${keypath}/hello | jq -r .node.value)
if [[ "${value}" != "world" ]]; then
  echo "Value retrived from curl -s $uri/v2/keys${keypath}/hello should be 'world', was '${value}'"
  exit 1
fi

delete_binding
delete_instance

echo "User's /hello should now be deleted"
missing_value=$(curl -s ${ETCD_URI:?required}/v2/keys${keypath}/hello | jq -r .node.value)
if [[ "${missing_value}" != "null" ]]; then
  echo "Expecting that all data within ${base_path} has been deleted"
  exit 1
fi

) 2>&1
