#!/usr/bin/env bash
# decide() branch coverage for platform-fallback.sh
set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PLATFORM_FALLBACK="${PLATFORM_FALLBACK_UNDER_TEST:-$SCRIPT_DIR/../bin/platform-fallback.sh}"
PLATFORM_FALLBACK_LIB=1
export PLATFORM_FALLBACK_LIB
# shellcheck source=/dev/null
source "$PLATFORM_FALLBACK"

fail=0
n=0
probe() { # want, reachable, remote_active, local_active, local_busy, streak
  local want="$1"; shift
  local got; got=$(decide "$@")
  n=$((n + 1))
  if [ "$got" != "$want" ]; then
    printf 'FAIL want=%-12s got=%-12s args=[%s]\n' "$want" "$got" "$*"
    fail=$((fail + 1))
  fi
}

#      want           reach remote_act local_act busy streak
probe  hold           1     1          0         0    0   # steady state: debian1 serving
probe  start-remote   1     0          0         0    0   # debian1 up, its runner died -> revive there
probe  recover        1     1          1         0    0   # split brain, laptop idle -> debian1 wins
probe  recover        1     0          1         0    0   # laptop holds session, debian1 back -> hand back
probe  hold           1     0          1         1    0   # laptop mid-job -> never evict, recover next poll
probe  hold           1     1          1         1    0   # same, even with debian1 already up
probe  hold           0     0          0         0    1   # one missed probe is a blip, not an outage
probe  failover       0     0          0         0    2   # sustained: laptop takes the session
probe  failover       0     0          0         0    9
probe  hold           0     0          1         0    3   # already failed over -> nothing to do
probe  hold           0     0          1         1    3   # failed over and working

mkdir -p "${XDG_CACHE_HOME:-$HOME/.cache}/overdeck/tests"
resolver_tmp="$(mktemp -d "${XDG_CACHE_HOME:-$HOME/.cache}/overdeck/tests/platform-fallback.XXXXXX")"
trap 'rm -rf "$resolver_tmp"' EXIT
mkdir -p "$resolver_tmp/bin" "$resolver_tmp/state"
cat >"$resolver_tmp/bin/node" <<'EOF'
#!/usr/bin/env bash
echo 'PATH node must not be used' >&2
exit 91
EOF
chmod +x "$resolver_tmp/bin/node"
cat >"$resolver_tmp/registry.json" <<'EOF'
{
  "schema_version": 1,
  "hosts": [
    {
      "name": "box-a",
      "ssh_alias": "box-a",
      "state": "reachable",
      "machine_id": null,
      "roles": ["builder"],
      "access": {
        "lan": null,
        "tailscale_ip": {"host":"100.64.0.10","port":2222,"user":"user","identity_file":"~/.ssh/test-buildbox"},
        "tailscale_ssh": {"host":"box-a.example.ts.net","port":22,"user":"user","identity_file":null}
      },
      "rustdesk": null,
      "notes": "fixture"
    }
  ],
  "orders": {"build":["box-a"]}
}
EOF
resolver_err="$resolver_tmp/resolver.err"
if (
  export PATH="$resolver_tmp/bin:$PATH"
  export BUILDBOX_HOSTS_CONFIG="$resolver_tmp/registry.json"
  export PLATFORM_FALLBACK_NODE_BIN=/usr/bin/node
  export PLATFORM_FALLBACK_STATE="$resolver_tmp/state"
  export PLATFORM_FALLBACK_LOG="$resolver_tmp/fallback.log"
  PLATFORM_FALLBACK_LIB=1
  # shellcheck source=/dev/null
  source "$PLATFORM_FALLBACK"
  resolve_remote
  [ "$REMOTE_NAME" = box-a ]
  [ "$REMOTE" = 100.64.0.10 ]
  [ "$REMOTE_PORT" = 2222 ]
) 2>"$resolver_err" && ! grep -q 'PATH node must not be used\|remote-only dispatch failed' "$resolver_err"; then
  n=$((n + 1))
else
  printf 'FAIL resolver used PATH node or failed local registry resolution\n'
  cat "$resolver_err"
  n=$((n + 1))
  fail=$((fail + 1))
fi

printf '%d probes, %d failures\n' "$n" "$fail"
exit $((fail > 0))
