#!/usr/bin/env bash
# Tests for resume-tunnel.sh scope-based spawn path (Task 602).
# Stubs systemd-run, systemctl, and cloudflared binaries via a fake $PATH entry.
set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RESUME="$SCRIPT_DIR/../resume-tunnel.sh"

PASS=0
FAIL=0

run_case() {
  local name="$1"; shift
  echo ""
  echo "=== CASE: $name ==="
  if "$@"; then
    PASS=$((PASS + 1))
    echo "PASS: $name"
  else
    FAIL=$((FAIL + 1))
    echo "FAIL: $name"
  fi
}

# Build a minimal install tree with stubs and state file.
# Args: root config_dir scope_active connect_success
setup() {
  local root="$1"
  local config_dir="${2:-.maxy-code}"
  local scope_active="${3:-inactive}"
  local connect_success="${4:-yes}"

  local home_dir="$root/home"
  local platform_root="$root/platform_root"
  local bin_dir="$root/bin"
  mkdir -p "$home_dir/$config_dir/cloudflared" \
           "$home_dir/$config_dir/logs" \
           "$platform_root/config" \
           "$bin_dir"

  cat > "$platform_root/config/brand.json" <<JSON
{"configDir": "$config_dir"}
JSON

  cat > "$home_dir/$config_dir/cloudflared/tunnel.state" <<JSON
{
  "tunnelId": "test-tunnel-id",
  "domain": "test.example.com",
  "configPath": "$home_dir/$config_dir/cloudflared/config.yml",
  "pid": 99999
}
JSON

  touch "$home_dir/$config_dir/cloudflared/cert.pem"
  touch "$home_dir/$config_dir/cloudflared/config.yml"

  local log_file="$home_dir/$config_dir/logs/cloudflared.log"

  # Stub cloudflared: does nothing.
  cat > "$bin_dir/cloudflared" <<'SH'
#!/bin/bash
sleep 0.1
SH
  chmod +x "$bin_dir/cloudflared"

  # Stub systemctl: is-active returns based on scope_active.
  cat > "$bin_dir/systemctl" <<SH
#!/bin/bash
if [[ "\$*" == *"is-active"* ]]; then
  if [[ "${scope_active}" == "active" ]]; then
    echo "active"; exit 0
  else
    echo "inactive"; exit 3
  fi
fi
if [[ "\$*" == *"--property=MainPID"* ]]; then
  echo "12345"
fi
exit 0
SH
  chmod +x "$bin_dir/systemctl"

  # Stub systemd-run: logs its --unit= and --slice= args, optionally writes connection line.
  cat > "$bin_dir/systemd-run" <<SH
#!/bin/bash
for arg in "\$@"; do
  case "\$arg" in
    --unit=*) echo "[stub] unit=\${arg#--unit=}" ;;
    --slice=*) echo "[stub] slice=\${arg#--slice=}" ;;
  esac
done
if [[ "${connect_success}" == "yes" ]]; then
  echo "2026-06-02T00:00:00Z INF Registered tunnel connection connIndex=0" >> "${log_file}"
fi
exit 0
SH
  chmod +x "$bin_dir/systemd-run"
}

cleanup() { rm -rf "$1"; }

# CASE 1: skip branch — scope is active
case_skip_when_scope_active() {
  local root
  root=$(mktemp -d /tmp/resume-tunnel-test-XXXXXX)
  setup "$root" ".maxy-code" "active" "yes"

  local log="$root/home/.maxy-code/logs/cloudflared.log"

  HOME="$root/home" \
  PATH="$root/bin:$PATH" \
  MAXY_PLATFORM_ROOT="$root/platform_root" \
    bash "$RESUME"
  local rc=$?

  local log_content
  log_content=$(cat "$log" 2>/dev/null || echo "")
  cleanup "$root"

  if [[ $rc -ne 0 ]]; then
    echo "  expected exit 0, got $rc"; return 1
  fi
  if ! echo "$log_content" | grep -q "already running.*scope.*cloudflared-maxy-code"; then
    echo "  skip branch missing expected log line"
    echo "$log_content"
    return 1
  fi
  return 0
}

# CASE 2: spawn branch — scope inactive, connection succeeds
case_spawn_succeeds() {
  local root
  root=$(mktemp -d /tmp/resume-tunnel-test-XXXXXX)
  setup "$root" ".maxy-code" "inactive" "yes"

  local log="$root/home/.maxy-code/logs/cloudflared.log"

  HOME="$root/home" \
  PATH="$root/bin:$PATH" \
  MAXY_PLATFORM_ROOT="$root/platform_root" \
    bash "$RESUME"
  local rc=$?

  local log_content
  log_content=$(cat "$log" 2>/dev/null || echo "")
  cleanup "$root"

  if [[ $rc -ne 0 ]]; then
    echo "  expected exit 0, got $rc"; return 1
  fi
  if ! echo "$log_content" | grep -q "spawned scope=cloudflared-maxy-code.scope"; then
    echo "  missing spawned scope log line"; echo "$log_content"; return 1
  fi
  if ! echo "$log_content" | grep -q "tunnel verified"; then
    echo "  missing tunnel verified log line"; echo "$log_content"; return 1
  fi
  return 0
}

# CASE 3: spawn branch — no edge connection within timeout
case_spawn_no_connection() {
  local root
  root=$(mktemp -d /tmp/resume-tunnel-test-XXXXXX)
  setup "$root" ".maxy-code" "inactive" "no"

  local log="$root/home/.maxy-code/logs/cloudflared.log"

  HOME="$root/home" \
  PATH="$root/bin:$PATH" \
  MAXY_PLATFORM_ROOT="$root/platform_root" \
  RESUME_TUNNEL_VERIFY_DEADLINE=2 \
    bash "$RESUME"
  local rc=$?

  local log_content
  log_content=$(cat "$log" 2>/dev/null || echo "")
  cleanup "$root"

  if [[ $rc -ne 0 ]]; then
    echo "  expected exit 0 even on failure, got $rc"; return 1
  fi
  if ! echo "$log_content" | grep -q "ERROR.*no edge connection"; then
    echo "  missing ERROR log line on connection failure"; echo "$log_content"; return 1
  fi
  return 0
}

# CASE 4: scope unit name derived correctly from configDir (.real-agent → cloudflared-real-agent.scope)
case_scope_unit_name_from_config_dir() {
  local root
  root=$(mktemp -d /tmp/resume-tunnel-test-XXXXXX)
  setup "$root" ".real-agent" "inactive" "yes"

  local log="$root/home/.real-agent/logs/cloudflared.log"

  HOME="$root/home" \
  PATH="$root/bin:$PATH" \
  MAXY_PLATFORM_ROOT="$root/platform_root" \
    bash "$RESUME"
  local rc=$?

  local log_content
  log_content=$(cat "$log" 2>/dev/null || echo "")
  cleanup "$root"

  if [[ $rc -ne 0 ]]; then
    echo "  expected exit 0, got $rc"; return 1
  fi
  if ! echo "$log_content" | grep -q "spawned scope=cloudflared-real-agent.scope"; then
    echo "  scope unit name not derived correctly from .real-agent"
    echo "$log_content"; return 1
  fi
  return 0
}

# CASE 5: --slice=cloudflared flag passed to systemd-run
case_slice_flag_present() {
  local root
  root=$(mktemp -d /tmp/resume-tunnel-test-XXXXXX)
  setup "$root" ".maxy-code" "inactive" "yes"

  local log="$root/home/.maxy-code/logs/cloudflared.log"

  HOME="$root/home" \
  PATH="$root/bin:$PATH" \
  MAXY_PLATFORM_ROOT="$root/platform_root" \
    bash "$RESUME"

  local log_content
  log_content=$(cat "$log" 2>/dev/null || echo "")
  cleanup "$root"

  # The systemd-run stub echoes "[stub] slice=cloudflared" to stdout,
  # which is redirected to LOG_FILE by the script's >> redirect.
  if ! echo "$log_content" | grep -q "\[stub\] slice=cloudflared"; then
    echo "  --slice=cloudflared not seen by systemd-run stub"
    echo "$log_content"; return 1
  fi
  return 0
}

run_case "skip when scope active" case_skip_when_scope_active
run_case "spawn succeeds and logs verified" case_spawn_succeeds
run_case "spawn with no connection logs ERROR exits 0" case_spawn_no_connection
run_case "scope unit name derived from configDir" case_scope_unit_name_from_config_dir
run_case "slice flag passed to systemd-run" case_slice_flag_present

echo ""
echo "Results: $PASS passed, $FAIL failed"
[[ $FAIL -eq 0 ]]
