#!/usr/bin/env bash

while getopts 'hr' flag; do
  case "${flag}" in
  h) printf '\n'
     printf '%s\n' "This script builds images and runs containers using docker-compose"
     printf '\n'
     printf '%s\n' "-h: Print this message"
     printf '%s\n' "-r: Also run the built container. This assumes credentials have been configured."
     exit 0;;
  r) RUN_CONTAINER=true ;;
  *) printf '%s\n' "Unexpected option ${flag}"
     exit 1 ;;
  esac
done

GIT_BINARY=$(/usr/bin/which git)
LATEST_COMMIT=$(git rev-parse HEAD)
PREVIOUS_COMMIT=$(git rev-parse HEAD~1)
ROOT_DIR=$(pwd)
BUILT_DIRS=()

printf '%s\n' "Checking revision ${LATEST_COMMIT} against ${PREVIOUS_COMMIT}"

# Get changed files. Exclude copied, deleted, or renamed files since they no longer exist.
CHANGED_FILES=( $(${GIT_BINARY} diff-tree --no-commit-id --name-only --diff-filter=cdr -r "${PREVIOUS_COMMIT}" "${LATEST_COMMIT}") )

for file in "${CHANGED_FILES[@]}"; do
  TARGET_DIRECTORY=$(echo "${file}" | cut -d '/' -f 1)
  # Only build if we haven't built it yet
  if [[ ! "${BUILT_DIRS[@]}" =~ ${TARGET_DIRECTORY} ]]; then
    printf '%s\n' "Testing docker build for ${TARGET_DIRECTORY}"
    cd "${ROOT_DIR}/${TARGET_DIRECTORY}" || exit 1
    if [ "${TARGET_DIRECTORY}" = 'ksqldb_server' ]; then
      printf '%s\n' "Building with args for ${TARGET_DIRECTORY}"
      docker-compose build --no-cache --build-arg GITHUB_TOKEN="${GITHUB_TOKEN}" --build-arg GITHUB_USERNAME="${GITHUB_USERNAME}"
    elif [ "${TARGET_DIRECTORY}" = 'build' ]; then
      printf '%s\n' "Skipping build directory"
    else
      docker-compose build --no-cache 
    fi
    # Add to array so we don't build twice if multiple files in same dir were changed
    BUILT_DIRS+=("${TARGET_DIRECTORY}")

    # TODO (Do this by default, if we can safely and easily seed dev credentials for each connector. For now it's an option.)
    if [ "${RUN_CONTAINER}" = 'true' ] && [ "${TARGET_DIRECTORY}" != 'build' ]; then
      docker-compose up -d
      # Sleep for up to 5 minutes
      for interval in {1..30}; do
        STATUS=$(docker inspect --format "{{json .State.Health }}" "$(docker-compose ps -q)" | jq -r '.Status')
        if [ "${STATUS}" = 'healthy' ]; then
          printf '%s\n' "$(date): Task is healthy"
          docker-compose down
          printf '%s\n' "$(date): Stopped container"
          break
        else
          if [ "${interval}" = 30 ]; then
            printf '%s\n' "$(date): Task is not healthy and grace period has been exhausted" && exit 1
          else
            printf '%s\n' "$(date): Task is not healthy. Waiting 10 seconds..."
            sleep 10
          fi
        fi
      done
    fi
  else
    printf '%s\n' "Directory ${TARGET_DIRECTORY} already built and tested"
  fi
done
