#!/bin/bash
#
#  Copyright 2020 gRPC authors.
#
#  Licensed 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

export TMPDIR=$(mktemp -d)
trap "rm -rf ${TMPDIR}" EXIT

clean () {
  for i in {1..10}; do
    jobs -p | xargs -n1 pkill -P
    # A simple "wait" just hangs sometimes.  Running `jobs` seems to help.
    sleep 1
    if jobs | read; then
      return
    fi
  done
  echo "$(tput setaf 1) clean failed to kill tests $(tput sgr 0)"
  jobs
  pstree
  rm ${CLIENT_LOG}
  rm ${SERVER_LOG}
  rm ${KEY_FILE_PATH}
  rm ${CERT_FILE_PATH}
  exit 1
}

fail () {
    echo "$(tput setaf 1) $1 $(tput sgr 0)"
    clean
    exit 1
}

pass () {
    echo "$(tput setaf 2) $1 $(tput sgr 0)"
}

EXAMPLES=(
    "credential_reloading_from_files"
)

declare -a EXPECTED_SERVER_OUTPUT=("Client common name: foo.bar.hoo.com" "Client common name: foo.bar.another.client.com")

cd ./security/advancedtls/examples

for example in ${EXAMPLES[@]}; do
    echo "$(tput setaf 4) testing: ${example} $(tput sgr 0)"

    KEY_FILE_PATH=$(mktemp)
    cat ../testdata/client_key_1.pem > ${KEY_FILE_PATH}

    CERT_FILE_PATH=$(mktemp)
    cat ../testdata/client_cert_1.pem > ${CERT_FILE_PATH}

    # Build server.
    if ! go build -o /dev/null ./${example}/*server/*.go; then
        fail "failed to build server"
    else
        pass "successfully built server"
    fi

    # Build client.
    if ! go build -o /dev/null ./${example}/*client/*.go; then
        fail "failed to build client"
    else
        pass "successfully built client"
    fi

    # Start server.
    SERVER_LOG="$(mktemp)"
    go run ./$example/*server/*.go &> $SERVER_LOG  &

    # Run client binary.
    CLIENT_LOG="$(mktemp)"
    go run ${example}/*client/*.go -key=${KEY_FILE_PATH} -cert=${CERT_FILE_PATH} &> $CLIENT_LOG  &

    # Wait for the client to send some requests using old credentials.
    sleep 4s

    # Switch to the new credentials.
    cat ../testdata/another_client_key_1.pem > ${KEY_FILE_PATH}
    cat ../testdata/another_client_cert_1.pem > ${CERT_FILE_PATH}

    # Wait for the client to send some requests using new credentials.
    sleep 4s

    # Check server log for expected output.
    for output in "${EXPECTED_SERVER_OUTPUT[@]}"; do
      if ! grep -q "$output" $SERVER_LOG; then
          fail "server log missing output: $output
          got server log:
          $(cat $SERVER_LOG)
          "
      else
          pass "server log contains expected output: $output"
      fi
    done

    clean
done
