#!/usr/bin/env bash
# clawforge — Unified CLI for agent swarm workflow
# Routes subcommands to individual module scripts.
set -euo pipefail

# Resolve symlinks to find the real install location
SOURCE="${BASH_SOURCE[0]}"
while [[ -L "$SOURCE" ]]; do
  DIR="$(cd "$(dirname "$SOURCE")" && pwd)"
  SOURCE="$(readlink "$SOURCE")"
  [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE"
done
CLAWFORGE_DIR="$(cd "$(dirname "$SOURCE")/.." && pwd)"
BIN_DIR="${CLAWFORGE_DIR}/bin"

# ── Global flags ───────────────────────────────────────────────────────
PASSTHROUGH_ARGS=()
for arg in "$@"; do
  if [[ "$arg" == "--verbose" ]]; then
    export CLAWFORGE_DEBUG=1
  else
    PASSTHROUGH_ARGS+=("$arg")
  fi
done
set -- "${PASSTHROUGH_ARGS[@]+"${PASSTHROUGH_ARGS[@]}"}"

# ── Version ────────────────────────────────────────────────────────────
show_version() {
  local ver
  ver=$(cat "${CLAWFORGE_DIR}/VERSION" 2>/dev/null || echo "unknown")
  echo "clawforge v${ver}"
}

# ── Help ───────────────────────────────────────────────────────────────
show_help() {
  local show_all=false
  [[ "${1:-}" == "--all" ]] && show_all=true

  cat <<EOF
$(show_version)
Multi-mode coding workflow CLI — from quick patches to parallel agent orchestration.

Usage: clawforge <command> [options]

Workflow Modes:
  quick-run   Direct agent execution in cwd (no branch/worktree overhead)
  sprint      Single agent, full dev cycle (the workhorse)
  review      Quality gate on an existing PR (analysis only)
  swarm       Parallel multi-agent orchestration

Management:
  status      Show all tracked tasks with short IDs
  resume      Resume a failed/timeout task from where it left off
  diff        Show git diff for a task without attaching
  pr          Create a PR from a task branch
  attach      Attach to a running agent's tmux session
  steer       Send course correction to a running agent
  stop        Stop a running agent
  watch       Monitor agent health (supports --daemon)
  dashboard   Live TUI dashboard with vim keybindings

Observability (v0.5):
  cost        Token/cost tracking and budget management
  conflicts   Swarm conflict detection and resolution
  templates   Task template management

Fleet Ops (v0.6):
  memory      Per-repo agent memory (show, add, search, forget, clear)
  init        Scan project and generate initial memory entries
  history     Show completed task history

Reliability (v0.7):
  doctor      Diagnose orphaned sessions, dangling worktrees, stale tasks

Observability (v0.9):
  logs        Capture agent output from tmux (without attaching)
  on-complete Fire completion hooks for finished tasks

Power Features (v1.2):
  config      Manage user configuration (~/.clawforge/config.json)
  multi-review Run PR through multiple models and compare feedback
  summary     AI-generated summary of what an agent did
  parse-cost  Parse real cost/token data from agent output

Web Dashboard (v1.4):
  web         Launch web dashboard (accessible from phone/browser)
  deps        Show task dependency graph / blocked tasks

Developer Experience (v1.3):
  profile     Manage reusable agent profiles (presets)
  replay      Re-run a completed task with same parameters
  export      Export task history as markdown/JSON report
  completions Install shell tab completions (bash/zsh/fish)

Evaluation (v0.6.2):
  eval        Run-eval logging and weekly summaries

Lifecycle:
  clean       Clean up completed tasks
  learn       Record learnings from completed tasks
EOF

  if $show_all; then
    cat <<EOF

Direct Module Access:
  scope       Assemble a prompt with context (Module 1)
  spawn       Create worktree + launch coding agent (Module 2)
  notify      Send Discord notification (Module 6)
  merge       Merge helper with safety checks (Module 7)
  run         Scope + spawn in one step (legacy shortcut)
EOF
  fi

  cat <<EOF

Meta:
  help        Show this help (use --all for direct module commands)
  version     Show version

Global flags:
  --verbose   Enable debug logging

Examples:
  clawforge sprint "Add JWT authentication middleware"
  clawforge sprint "Fix typo in readme" --quick
  clawforge sprint --template refactor "Refactor auth module"
  clawforge review --pr 42
  clawforge swarm "Migrate all tests from jest to vitest"
  clawforge swarm --template migration "Migrate to TypeScript" --ci-loop
  clawforge swarm --repos ~/api,~/web,~/shared "Upgrade auth library"
  clawforge sprint --routing auto "Refactor auth service"
  clawforge steer 1 "Use bcrypt instead of md5"
  clawforge dashboard
  clawforge cost --summary
  clawforge memory show
  clawforge memory add "Always run tests first"
  clawforge init
  clawforge history --repo api
  clawforge eval log --command sprint --mode quick --repo api --status ok --duration-ms 420000
  clawforge eval weekly
  clawforge templates
EOF
}

# ── Dashboard (v0.5: routes to TUI, legacy fallback kept as show_dashboard_legacy) ─

# ── Run shortcut (scope + spawn) ──────────────────────────────────────
run_combined() {
  # Parse --repo, --branch, --task from args, pass rest to spawn
  local repo="" branch="" task=""
  local extra_args=()

  while [[ $# -gt 0 ]]; do
    case "$1" in
      --repo)     repo="$2"; shift 2 ;;
      --branch)   branch="$2"; shift 2 ;;
      --task)     task="$2"; shift 2 ;;
      *)          extra_args+=("$1"); shift ;;
    esac
  done

  if [[ -z "$repo" || -z "$branch" || -z "$task" ]]; then
    echo "Usage: clawforge run --repo <path> --branch <name> --task \"description\"" >&2
    echo "All three flags are required." >&2
    exit 1
  fi

  echo "── Step 1: Scope ─────────────────────────────────────────────"
  local prompt
  prompt=$("${BIN_DIR}/scope-task.sh" --task "$task" "${extra_args[@]+"${extra_args[@]}"}" 2>/dev/null || echo "$task")

  echo "── Step 2: Spawn ─────────────────────────────────────────────"
  "${BIN_DIR}/spawn-agent.sh" --repo "$repo" --branch "$branch" --task "$prompt" "${extra_args[@]+"${extra_args[@]}"}"
}

# ── Status (pretty wrapper around registry) ────────────────────────────
show_status() {
  source "${CLAWFORGE_DIR}/lib/common.sh"
  local tasks
  tasks=$(registry_list "$@" 2>/dev/null || echo "[]")
  local count
  count=$(echo "$tasks" | jq 'length' 2>/dev/null || echo 0)

  if [[ "$count" == "0" ]]; then
    echo "No active tasks."
    return 0
  fi

  # Enhanced status with short IDs and mode column
  echo "$tasks" | jq -r '.[] |
    def sid: if .short_id then "#\(.short_id)" else .id end;
    def mode: .mode // "—";
    def elapsed:
      (now * 1000 - (.startedAt // 0)) / 60000 | floor | tostring + "m ago";
    def extra:
      if .mode == "swarm" and .sub_task_count then " (\(.sub_task_count) agents)" else "" end;
    "  \(sid)  \(mode)  \(.status // "?")  \(.repo // "" | split("/") | last)  \"\(.description // "")[0:50]\"\(extra)"
  ' 2>/dev/null || \
  echo "$tasks" | jq -r '.[] | "[\(.status // "?")] \(.id)  \(.agent // "")/\(.model // "")  \(.task // .description // "")[0:60]"' 2>/dev/null || echo "$tasks"
}

# ── Route subcommand ───────────────────────────────────────────────────
COMMAND="${1:-help}"
shift 2>/dev/null || true

case "$COMMAND" in
  # Workflow modes (v0.4)
  sprint)     exec "${BIN_DIR}/sprint.sh" "$@" ;;
  review)     exec "${BIN_DIR}/review-mode.sh" "$@" ;;
  swarm)      exec "${BIN_DIR}/swarm.sh" "$@" ;;

  # Management commands (v0.4)
  steer)      exec "${BIN_DIR}/steer.sh" "$@" ;;
  attach)     exec "${BIN_DIR}/attach.sh" "$@" ;;
  stop)       exec "${BIN_DIR}/stop.sh" "$@" ;;

  # Existing commands
  status)     show_status "$@" ;;
  watch)      exec "${BIN_DIR}/check-agents.sh" "$@" ;;
  dashboard)
    # Prefer Go TUI binary if available, fallback to dashboard.sh
    if [[ -x "${BIN_DIR}/clawforge-dashboard" ]]; then
      exec "${BIN_DIR}/clawforge-dashboard" "$@"
    else
      exec "${BIN_DIR}/dashboard.sh" "$@"
    fi
    ;;
  clean)      exec "${BIN_DIR}/clean.sh" "$@" ;;
  learn)      exec "${BIN_DIR}/learn.sh" "$@" ;;

  # v0.5 observability + intelligence
  cost)       exec "${BIN_DIR}/cost.sh" "$@" ;;
  conflicts)  exec "${BIN_DIR}/conflicts.sh" "$@" ;;
  templates)  exec "${BIN_DIR}/templates.sh" "$@" ;;

  # v0.6 fleet operations
  memory)     exec "${BIN_DIR}/memory.sh" "$@" ;;
  init)       exec "${BIN_DIR}/init.sh" "$@" ;;
  history)    exec "${BIN_DIR}/history.sh" "$@" ;;
  eval)       exec "${BIN_DIR}/eval.sh" "$@" ;;
doctor)     exec "${BIN_DIR}/doctor.sh" "$@" ;;
  resume)     exec "${BIN_DIR}/resume.sh" "$@" ;;
  diff)       exec "${BIN_DIR}/diff.sh" "$@" ;;
  pr)         exec "${BIN_DIR}/pr.sh" "$@" ;;
  config)     exec "${BIN_DIR}/config.sh" "$@" ;;
  multi-review) exec "${BIN_DIR}/multi-review.sh" "$@" ;;
  summary)    exec "${BIN_DIR}/summary.sh" "$@" ;;
  parse-cost) exec "${BIN_DIR}/parse-cost.sh" "$@" ;;
  profile)    exec "${BIN_DIR}/profile.sh" "$@" ;;
  replay)     exec "${BIN_DIR}/replay.sh" "$@" ;;
  export)     exec "${BIN_DIR}/export.sh" "$@" ;;
  completions) exec "${BIN_DIR}/completions.sh" "$@" ;;
  web)        exec "${BIN_DIR}/web.sh" "$@" ;;
  deps)       exec "${BIN_DIR}/deps.sh" "$@" ;;
  logs)       exec "${BIN_DIR}/logs.sh" "$@" ;;
  on-complete) exec "${BIN_DIR}/on-complete.sh" "$@" ;;

  # Direct module access (hidden from main help)
  scope)      exec "${BIN_DIR}/scope-task.sh" "$@" ;;
  spawn)      exec "${BIN_DIR}/spawn-agent.sh" "$@" ;;
  notify)     exec "${BIN_DIR}/notify.sh" "$@" ;;
  merge)      exec "${BIN_DIR}/merge-helper.sh" "$@" ;;
  quick-run)  exec "${BIN_DIR}/quick-run.sh" "$@" ;;
  run)        run_combined "$@" ;;

  # Meta
  version|-v|--version) show_version ;;
  help|-h|--help)       show_help "$@" ;;
  *)
    echo "Unknown command: $COMMAND" >&2
    echo "Run 'clawforge help' for usage." >&2
    exit 1
    ;;
esac
