#! /usr/bin/env bash
# shellcheck disable=SC2064
# SC2064: Intentional use of early expansion for trap.
# shellcheck disable=SC2001
# SC2001: In this case, we can't use variable replacement
# because the `bash` on Windows doesn't support it and we
# are replacing special characters anyway.
# shellcheck disable=SC2317
# SC2317: Command can be reached.

export testdir=$(mktemp -d -t tst-XXXXXX) || exit 1
WATCHER=$(realpath "${WATCHER:-$(command -v wtr.watcher)}") || {
  echo WATCHER env var not set to a valid path and wtr.watcher not found in PATH 1>&2
  exit 1
}
for dep in jq diff portable-destructive-rename
do command -v "$dep" &> /dev/null || { echo "$dep" not found in PATH 1>&2 ; exit 1 ; }
done

trap "cd '$PWD' ; rm -rf '$testdir' '$testdir.json'" EXIT
cd "$testdir" || exit 1

# Otherwise, the Darwin watcher will see the testdir's creation event
[ "$(uname -s)" = Darwin ] && sleep 0.2

strip-tmpdir() {
  # Darwin prepends /private to tmp dirs
  sed -E "s;$1|/private$1;d;g" "$2"
}

watch-async() {
  "$WATCHER" "$@" &
  sleep 0.1
}
export -f watch-async

show-output() {
  d=$1
  f=$d.json

  strip-tmpdir "$d" "$f" \
  | jq '
    { path_type: .path_type
    , path_name: .path_name
    , effect_type: .effect_type
    , effect_time: .effect_time
    , associated: .associated
    } | to_entries | sort_by(.path_name) | from_entries' \
  | jq --slurp -S
}
export -f show-output

show-events() {
  show-output "$@" | jq
}
export -f show-events

without-effect-time() {
 sed '/"effect_time":/d'
}
export -f without-effect-time

without-self-events() {
  jq -c '.[] | select(.path_type != "watcher")'
}
export -f without-self-events

check-result() {
  [[ -z "$1" || -z "$2" ]] && return 1
  expect=$1
  actual=$2
  lhs() { echo "$expect" | jq -S; }
  rhs() { echo "$actual" | jq -S | sed '/"associated": null,/d'; }
  if diff <(lhs) <(rhs) &> /dev/null
  then echo ':) ok'
  else echo 'oops :(' && diff --side-by-side <(lhs) <(rhs)
  fi
}
export -f check-result
