#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
DECKCTL="$ROOT/bin/deckctl"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

pass=0
fail=0

ok() {
  pass=$((pass + 1))
  printf 'PASS %s\n' "$1"
}

bad() {
  fail=$((fail + 1))
  printf 'FAIL %s\n' "$1"
}

write_fixture_registry() {
  local path="$1"
  cat >"$path" <<'EOF'
{
  "schema_version": 1,
  "hosts": [
    {
      "name": "registry-stub",
      "ssh_alias": "registry-stub",
      "state": "reachable",
      "machine_id": null,
      "roles": ["builder"],
      "access": {
        "lan": null,
        "tailscale_ip": { "host": "100.64.0.9", "port": 2222, "user": "user", "identity_file": null },
        "tailscale_ssh": null
      },
      "rustdesk": null,
      "notes": "registry-stub fixture"
    },
    {
      "name": "debian1",
      "ssh_alias": "debian1",
      "state": "unreachable",
      "machine_id": null,
      "roles": ["builder"],
      "access": {
        "lan": null,
        "tailscale_ip": { "host": "100.64.0.1", "port": 2222, "user": "user", "identity_file": null },
        "tailscale_ssh": null
      },
      "rustdesk": null,
      "notes": "debian1 fixture"
    },
    {
      "name": "debian2",
      "ssh_alias": "debian2",
      "state": "unreachable",
      "machine_id": null,
      "roles": ["builder"],
      "access": {
        "lan": null,
        "tailscale_ip": { "host": "100.64.0.2", "port": 2222, "user": "user", "identity_file": null },
        "tailscale_ssh": null
      },
      "rustdesk": null,
      "notes": "debian2 fixture"
    },
    {
      "name": "debian3",
      "ssh_alias": "debian3",
      "state": "unreachable",
      "machine_id": null,
      "roles": ["builder"],
      "access": {
        "lan": null,
        "tailscale_ip": { "host": "100.64.0.3", "port": 2222, "user": "user", "identity_file": null },
        "tailscale_ssh": null
      },
      "rustdesk": null,
      "notes": "debian3 fixture"
    }
  ],
  "orders": {
    "build": ["registry-stub"]
  }
}
EOF
}

write_fixture_fleet() {
  local path="$1"
  cat >"$path" <<'EOF'
{
  "schema_version": 1,
  "nodes": {
    "workstation": {
      "transport": "local",
      "roles": ["control", "agent-runtime"],
      "profiles": ["shared-agent-tools", "workstation"],
      "execution": "last-resort"
    },
    "debian1": {
      "transport": "ssh",
      "host_ref": "debian1",
      "roles": ["builder", "agent-runtime"],
      "profiles": ["shared-agent-tools", "buildbox", "buildbox-root"],
      "execution": "normal"
    },
    "debian2": {
      "transport": "ssh",
      "host_ref": "debian2",
      "roles": ["builder", "agent-runtime"],
      "profiles": ["shared-agent-tools", "buildbox", "buildbox-root"],
      "execution": "normal"
    },
    "debian3": {
      "transport": "ssh",
      "host_ref": "debian3",
      "roles": ["builder", "agent-runtime"],
      "profiles": ["shared-agent-tools", "buildbox", "buildbox-root"],
      "execution": "normal"
    }
  },
  "fallback": {
    "enabled": true,
    "node": "workstation",
    "requires_all_unavailable": ["debian1", "debian2", "debian3"],
    "max_concurrent_local_jobs": 1,
    "activation_windows": 3,
    "health_window_sec": 60,
    "lease_ttl_sec": 900
  }
}
EOF
}

setup_poison_path() {
  mkdir -p "$TMP/bin"
  cat >"$TMP/bin/ssh" <<'EOF'
#!/usr/bin/env bash
echo "poison ssh invoked: $*" >&2
touch "${DECKCTL_FLEET_POISON_MARKER:?}"
exit 99
EOF
  cat >"$TMP/bin/scp" <<'EOF'
#!/usr/bin/env bash
echo "poison scp invoked: $*" >&2
touch "${DECKCTL_FLEET_POISON_MARKER:?}"
exit 99
EOF
  chmod +x "$TMP/bin/ssh" "$TMP/bin/scp"
}

FLEET_FILE="$TMP/fleet.json"
REGISTRY_FILE="$TMP/buildbox-hosts.json"
POISON_MARKER="$TMP/poison-touched"
write_fixture_fleet "$FLEET_FILE"
write_fixture_registry "$REGISTRY_FILE"
setup_poison_path

export DECKCTL_FLEET_FILE="$FLEET_FILE"
export BUILDBOX_HOSTS_CONFIG="$REGISTRY_FILE"
export DECKCTL_FLEET_POISON_MARKER="$POISON_MARKER"
export PATH="$TMP/bin:$PATH"

set +e
"$DECKCTL" fleet >"$TMP/no-verb.stdout" 2>"$TMP/no-verb.stderr"
rc_no_verb=$?
set -e
if [[ $rc_no_verb -eq 2 ]] && grep -q 'usage: deckctl fleet' "$TMP/no-verb.stderr"; then
  ok 'no verb exits 2 with usage'
else
  bad "no verb exits 2 with usage (rc=$rc_no_verb)"
fi

set +e
"$DECKCTL" fleet not-a-verb >"$TMP/unknown.stdout" 2>"$TMP/unknown.stderr"
rc_unknown=$?
set -e
if [[ $rc_unknown -eq 2 ]] && grep -q 'usage: deckctl fleet' "$TMP/unknown.stderr"; then
  ok 'unknown verb exits 2 with usage'
else
  bad "unknown verb exits 2 with usage (rc=$rc_unknown)"
fi

set +e
"$DECKCTL" fleet audit no-such-node >"$TMP/bad-node.stdout" 2>"$TMP/bad-node.stderr"
rc_bad_node=$?
set -e
if [[ $rc_bad_node -ne 0 ]] && grep -q '"no-such-node"' "$TMP/bad-node.stderr"; then
  ok 'undeclared node exits nonzero naming it'
else
  bad "undeclared node exits nonzero naming it (rc=$rc_bad_node stderr=$(tr '\n' ' ' <"$TMP/bad-node.stderr"))"
fi

rm -f "$POISON_MARKER"
set +e
"$DECKCTL" fleet converge no-such-node >"$TMP/bad-converge.stdout" 2>"$TMP/bad-converge.stderr"
rc_bad_converge=$?
set -e
if [[ $rc_bad_converge -ne 0 ]] && grep -q '"no-such-node"' "$TMP/bad-converge.stderr" && [[ ! -e "$POISON_MARKER" ]]; then
  ok 'converge with undeclared node performs zero transport writes'
else
  bad "converge with undeclared node performs zero transport writes (rc=$rc_bad_converge marker=$([[ -e $POISON_MARKER ]] && echo yes || echo no))"
fi

set +e
"$DECKCTL" fleet harden >"$TMP/harden-zero.stdout" 2>"$TMP/harden-zero.stderr"
rc_harden_zero=$?
set -e
if [[ $rc_harden_zero -ne 0 ]]; then
  ok 'harden with zero nodes exits nonzero'
else
  bad 'harden with zero nodes exits nonzero'
fi

set +e
"$DECKCTL" fleet harden debian1 debian2 >"$TMP/harden-two.stdout" 2>"$TMP/harden-two.stderr"
rc_harden_two=$?
set -e
if [[ $rc_harden_two -ne 0 ]]; then
  ok 'harden with two nodes exits nonzero'
else
  bad 'harden with two nodes exits nonzero'
fi

rm -f "$POISON_MARKER"
set +e
"$DECKCTL" fleet harden no-such-node >"$TMP/harden-bad.stdout" 2>"$TMP/harden-bad.stderr"
rc_harden_bad=$?
set -e
if [[ $rc_harden_bad -ne 0 ]] && grep -q '"no-such-node"' "$TMP/harden-bad.stderr" && [[ ! -e "$POISON_MARKER" ]]; then
  ok 'harden with undeclared node exits nonzero naming it before any work'
else
  bad "harden with undeclared node exits nonzero naming it before any work (rc=$rc_harden_bad)"
fi

rm -f "$POISON_MARKER"
set +e
"$DECKCTL" fleet harden workstation >"$TMP/harden-ws.stdout" 2>"$TMP/harden-ws.stderr"
rc_harden_ws=$?
set -e
if [[ $rc_harden_ws -ne 0 ]] && grep -q 'workstation' "$TMP/harden-ws.stderr" && [[ ! -e "$POISON_MARKER" ]]; then
  ok 'harden refuses a non-buildbox node'
else
  bad "harden refuses a non-buildbox node (rc=$rc_harden_ws)"
fi

rm -f "$POISON_MARKER"
set +e
"$DECKCTL" fleet status >"$TMP/status.stdout" 2>"$TMP/status.stderr"
rc_status=$?
set -e
if [[ $rc_status -eq 0 ]]; then
  ws=$(grep -n 'node=workstation' "$TMP/status.stdout" | head -1 | cut -d: -f1)
  d1=$(grep -n 'node=debian1' "$TMP/status.stdout" | head -1 | cut -d: -f1)
  d2=$(grep -n 'node=debian2' "$TMP/status.stdout" | head -1 | cut -d: -f1)
  d3=$(grep -n 'node=debian3' "$TMP/status.stdout" | head -1 | cut -d: -f1)
  if [[ -n $ws && -n $d1 && -n $d2 && -n $d3 && $ws -lt $d1 && $d1 -lt $d2 && $d2 -lt $d3 ]]; then
    ok 'status lists all four nodes in declaration order'
  else
    bad "status lists all four nodes in declaration order (lines ws=$ws d1=$d1 d2=$d2 d3=$d3)"
  fi
else
  bad "status exits zero (rc=$rc_status stderr=$(tr '\n' ' ' <"$TMP/status.stderr"))"
fi

if [[ ! -e "$POISON_MARKER" ]]; then
  ok 'status never invoked poisoned ssh/scp'
else
  bad 'status never invoked poisoned ssh/scp'
fi

INSTALL_ROOT="$TMP/installed"
CALLER_ROOT="$TMP/caller"
mkdir -p "$INSTALL_ROOT/bin" "$INSTALL_ROOT/lib/deckctl" "$CALLER_ROOT/nested" "$TMP/launcher-bin" "$TMP/non-git"
cp "$ROOT/bin/deckctl" "$INSTALL_ROOT/bin/deckctl"
cp "$ROOT/lib/deckctl/fleet.sh" "$INSTALL_ROOT/lib/deckctl/fleet.sh"
chmod +x "$INSTALL_ROOT/bin/deckctl"
git -C "$CALLER_ROOT" init -q
git -C "$CALLER_ROOT" config user.email fixture@example.test
git -C "$CALLER_ROOT" config user.name fixture
printf 'fixture\n' >"$CALLER_ROOT/README"
git -C "$CALLER_ROOT" add README
git -C "$CALLER_ROOT" commit -qm fixture
cat >"$TMP/launcher-bin/node" <<'EOF'
#!/usr/bin/env bash
printf '%s|%s\n' "${DECKCTL_PROJECT_ROOT:-}" "$PWD"
EOF
chmod +x "$TMP/launcher-bin/node"
launcher_out=$(cd "$CALLER_ROOT/nested" && PATH="$TMP/launcher-bin:$PATH" "$INSTALL_ROOT/bin/deckctl" fleet audit)
if [[ "$launcher_out" == "$CALLER_ROOT|$INSTALL_ROOT" ]]; then
  ok 'installed fleet launcher carries caller git root across install cwd'
else
  bad "installed fleet launcher carries caller git root across install cwd (got=$launcher_out)"
fi
set +e
nongit_out=$(cd "$TMP/non-git" && PATH="$TMP/launcher-bin:$PATH" "$INSTALL_ROOT/bin/deckctl" fleet audit 2>&1)
rc_nongit=$?
set -e
if [[ $rc_nongit -ne 0 && "$nongit_out" == *'fleet must run from inside a Git checkout'* ]]; then
  ok 'installed fleet launcher rejects a caller outside git'
else
  bad "installed fleet launcher rejects a caller outside git (rc=$rc_nongit out=$nongit_out)"
fi

printf '\n%d passed, %d failed\n' "$pass" "$fail"
[[ "$fail" -eq 0 ]]
