#!/usr/bin/env bash
# TVAnarchy task runner. Thin, discoverable wrapper over the repo's build/test
# scripts so the common actions have one obvious name. Add a target by giving it
# a `task::<name>` function below — it shows up in `./run help` automatically.
#
#   ./run          # Debug build + relaunch (the everyday dev loop)
#   ./run dev      # same
#   ./run deploy   # Release install + relaunch (+ iOS when a phone is up)
#   ./run test     # Run Xcode unit tests
#   ./run clean    # Remove generated xcodeproj + build/
#   ./run governor # Run the governor (portable-net-tv)
#   ./run mcp      # Run the MCP server (stdio)
#   ./run bridge   # Run the HTTP bridge for iOS
#   ./run typecheck # TS typecheck for helpers
#   ./run test:all # App tests + governor + mcp + search
set -euo pipefail
cd "$(dirname "$0")"

DD="${TVANARCHY_DD:-build/dd}"

relaunch_tv_anarchy() {
  local app="$1"
  if pgrep -fq "TVAnarchy.app/Contents/MacOS"; then
    echo "→ quit running TVAnarchy"
    osascript -e 'quit app "TVAnarchy"' || true
    for _ in $(seq 1 20); do
      pgrep -fq "TVAnarchy.app/Contents/MacOS" || break
      sleep 0.5
    done
  fi
  echo "→ open $app"
  open "$app"
}

# Debug build from build/dd and relaunch — the default `./run`.
# Everyday loop: stamp → xcodegen → debug build → install to Applications → relaunch.
task::dev() {
  echo "→ stamp build identity"
  tools/stamp-build.sh

  echo "→ xcodegen generate"
  xcodegen generate >/dev/null

  local app="$DD/Build/Products/Debug/TVAnarchy.app"
  echo "→ xcodebuild (Debug → $app)"
  xcodebuild -scheme TVAnarchy -configuration Debug -derivedDataPath "$DD" \
    -destination 'platform=macOS' build CODE_SIGNING_ALLOWED=NO \
    2>&1 | grep -E 'BUILD SUCCEEDED|BUILD FAILED|error:' || true

  [ -d "$app" ] || { echo "✗ build produced no app at $app" >&2; exit 1; }

  # Install to /Applications (or ~/Applications) so Spotlight launches this build,
  # not a stale copy left from an old release cut.
  . tools/platform.sh
  local dest
  dest="$(tva_resolve_dest mac)"
  mkdir -p "$(dirname "$dest")"
  rm -rf "$dest"
  cp -R "$app" "$dest"
  VER=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$dest/Contents/Info.plist")
  BUILD=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "$dest/Contents/Info.plist")
  echo "✓ installed v$VER (build $BUILD) → $dest"

  relaunch_tv_anarchy "$dest"
}

# Release install to Applications (+ iOS when reachable). See deploy.sh.
task::deploy() { ./deploy.sh "$@"; }

# plum: build Release and install to ~/Applications or /Applications (no relaunch).
task::update:plum() { ./build-install.sh "$@"; }

# Regenerate the Xcode project from project.yml.
task::generate() { xcodegen generate; }

# Run the unit-test bundle (regenerates the project first so new files are picked
# up). Pass extra args straight through, e.g. `./run test -only-testing:...`.
task::help() { usage; }
task::test() {
  xcodegen generate >/dev/null
  xcodebuild test -project TVAnarchy.xcodeproj -scheme TVAnarchy \
    -destination 'platform=macOS' "$@"
}

# Clean generated Xcode project and derived data (safe; no source touch).
task::clean() {
  echo "→ rm -rf build/ TVAnarchy.xcodeproj"
  rm -rf build/ TVAnarchy.xcodeproj
}

# Typecheck the TypeScript helpers (governor + mcp).
task::typecheck() {
  echo "→ governor typecheck"
  (cd governor && bun run typecheck)
  echo "→ mcp typecheck"
  (cd mcp && bun run typecheck)
}

# Run the governor (portable-net-tv) — watch tracking + fleet engine on plum.
# Example: ./run governor fleet status
task::governor() {
  (cd governor && bun run src/index.ts "$@")
}

# Run the mcp stdio server (for MCP clients like Claude).
task::mcp() {
  (cd mcp && bun run src/index.ts "$@")
}

# Run the HTTP bridge (for iOS companion; default :8787).
task::bridge() {
  (cd mcp && bun run src/http.ts "$@")
}

# Deploy to phone (iOS build + sideload via tools/deploy-phone.sh).
task::deploy:phone() { tools/deploy-phone.sh "$@"; }

# Run full tests: app unit tests + governor + mcp (+ search pytest if present).
task::test:all() {
  task::test
  echo "→ governor test"
  (cd governor && bun test)
  echo "→ mcp test"
  (cd mcp && bun test)
  if [ -f search/pyproject.toml ]; then
    echo "→ search pytest"
    (cd search && uv run pytest -q || true)
  fi
}

usage() {
  echo "usage: ./run [target] [args...]"
  echo
  echo "  ./run, ./run dev   Debug build (stamp + xcodegen + Debug xcodebuild) + install to"
  echo "                     Applications (or ~/Applications) + quit + relaunch TVAnarchy."
  echo "                     This is the normal local dev loop (uses build/dd by default;"
  echo "                     set TVANARCHY_DD to relocate)."
  echo
  echo "Common targets:"
  echo "  deploy             Release build + publish flow (see deploy.sh)"
  echo "  update:plum        Release build + install (no relaunch; see build-install.sh)"
  echo "  deploy:phone       Build + install to connected iOS device"
  echo "  test               Run macOS unit tests (xcodebuild test)"
  echo "  test:all           App tests + governor bun test + mcp bun test + search pytest"
  echo "  clean              rm -rf build/ TVAnarchy.xcodeproj"
  echo "  generate           xcodegen generate (project.yml → .xcodeproj)"
  echo "  governor [...]     Run governor (portable-net-tv) with args (e.g. fleet status)"
  echo "  mcp [...]          Run mcp stdio server"
  echo "  bridge [...]       Run mcp HTTP bridge (for iOS companion)"
  echo "  typecheck          tsc --noEmit in governor/ and mcp/"
  echo
  echo "All targets (auto-discovered):"
  declare -F | sed -n 's/^declare -f task::/  /p' | grep -v '  help$'
  echo
  echo "See docs/operations.md and the top of this file for more."
}

main() {
  local target="${1:-dev}"
  [ "$target" != help ] || { usage; exit 0; }
  shift || true
  if ! declare -F "task::$target" >/dev/null; then
    echo "✗ unknown target: $target" >&2
    echo >&2
    usage >&2
    exit 1
  fi
  "task::$target" "$@"
}

main "$@"