/**
 * Phase 7.0 — HMR perf marker names (B4 fix)
 *
 * Purpose: give Agent B (incremental bundled import), Agent A (reliability),
 * and Agent F (perf validation) a single vocabulary for marker names passed
 * to `mark()` / `measure()` / `withPerf()`.
 *
 * Why a shared module: in Phase 7.0 diagnostics we found that
 * `cli/commands/dev.ts:322-363`'s `handleSSRChange` chain has NO perf
 * markers — `dev:rebuild` wraps only `_doBuild`, so the true SSR rebuild
 * walltime (1.5~2 s vs 200ms target) is invisible. Without consistent
 * marker naming across agents, each would pick ad-hoc strings and
 * Agent F's benchmark script would have to grep for a hundred variants.
 *
 * When adding new markers:
 *   1. Add the constant here.
 *   2. Use it in production code as `mark(HMR_PERF.SSR_HANDLER_RELOAD)`
 *      (not a string literal).
 *   3. Update `docs/bun/phase-7-benchmarks.md` (Agent F owns it).
 *
 * References:
 *   docs/bun/phase-7-diagnostics/performance-reliability.md §2 B4
 *   docs/bun/phase-7-team-plan.md §3.2
 */

/**
 * All HMR-related perf markers. String literals are frozen — do not
 * mutate. Marker names follow the `<area>:<step>` convention so grep
 * and log aggregation work predictably.
 */
export const HMR_PERF = {
  // ─── File detection → build invocation ─────────────────────────────────

  /** Raw fs event received (watcher). */
  FILE_DETECT: "hmr:file-detect",

  /** After per-file debounce, before `handleFileChange()` runs. */
  DEBOUNCE_FLUSH: "hmr:debounce-flush",

  /** Coalesced batch dispatched to the rebuild path. */
  BATCH_DISPATCH: "hmr:batch-dispatch",

  // ─── Rebuild outer frame ───────────────────────────────────────────────

  /** Wall-clock from batch dispatch → WS broadcast complete. The P95
   *  target (≤50 ms island / ≤200 ms SSR / ≤500 ms cold) is measured on
   *  this marker. */
  REBUILD_TOTAL: "hmr:rebuild-total",

  /** `_doBuild` body (covers both `buildClientBundles` + SSR path). */
  DO_BUILD: "hmr:do-build",

  // ─── SSR handler reload chain (B4 newly-instrumented) ──────────────────

  /** `handleSSRChange` mutex section — from enter to exit. */
  SSR_HANDLER_RELOAD: "ssr:handler-reload",

  /** `bundledImport` call — the single largest SSR cost today. Incremental
   *  path (Agent B) should target near-zero on cache hits. */
  SSR_BUNDLED_IMPORT: "ssr:bundled-import",

  /** `clearDefaultRegistry` + `registeredLayouts.clear` (fast). */
  SSR_CLEAR_REGISTRY: "ssr:clear-registry",

  /** `registerManifestHandlers(manifest, true)` — per-route re-registration. */
  SSR_REGISTER_HANDLERS: "ssr:register-handlers",

  /** Prerender regeneration (issue #188 fix). Measures only the prerender
   *  re-run, not the HTML delivery. */
  PRERENDER_REGEN: "prerender:regen",

  // ─── Client bundle path ────────────────────────────────────────────────

  /** Per-island rebuild. Sub-marker of DO_BUILD when kind === "islands-only". */
  ISLAND_REBUILD: "island:rebuild",

  /** Framework bundle (runtime/router/vendor/devtools). Should be SKIPPED
   *  on common-dir rebuild (fire when skipFrameworkBundles === false). */
  FRAMEWORK_REBUILD: "framework:rebuild",

  /** Vendor shim build. Sub-marker of FRAMEWORK_REBUILD. */
  VENDOR_SHIM_BUILD: "framework:vendor-shim",

  // ─── HMR transport ─────────────────────────────────────────────────────

  /** Time to serialize + send to all connected clients. */
  HMR_BROADCAST: "hmr:broadcast",

  /** Replay buffer enqueue (B8). */
  HMR_REPLAY_ENQUEUE: "hmr:replay-enqueue",

  /** Client reconnect — `?since=<id>` processing. */
  HMR_REPLAY_FLUSH: "hmr:replay-flush",

  // ─── Incremental bundled import internals (Agent B) ────────────────────

  /** Import graph lookup for a root path. */
  INCR_GRAPH_LOOKUP: "incr:graph-lookup",

  /** Cache hit (no rebuild needed — changed file not in descendants). */
  INCR_CACHE_HIT: "incr:cache-hit",

  /** Cache miss (rebuild required). */
  INCR_CACHE_MISS: "incr:cache-miss",

  /** Graph rebuild after new build — updates descendants map. */
  INCR_GRAPH_UPDATE: "incr:graph-update",

  // ─── Cold boot path (Phase 7.1 B_gap — R0.3 diagnostic identified 9
  //     unmeasured stages accounting for 150~210 ms of the 626 ms cold
  //     start. Instrumenting these unlocks Tier 1 / Tier 2 optimizations.) ─

  /** `validateAndReport(rootDir)` — mandu.config.ts load + schema check. */
  BOOT_VALIDATE_CONFIG: "boot:validate-config",

  /** `validateRuntimeLockfile` — bun.lock check + advisory warnings. */
  BOOT_LOCKFILE_CHECK: "boot:lockfile-check",

  /** `loadEnv({ rootDir, env: "development" })` — .env / .env.development. */
  BOOT_LOAD_ENV: "boot:load-env",

  /** `startSqliteStore(rootDir)` — observability store (optional). Should
   *  become fire-and-forget in Tier 1 so it doesn't block ready. */
  BOOT_SQLITE_START: "boot:sqlite-start",

  /** `checkDirectory(guardConfig, rootDir)` — Architecture Guard preflight. */
  BOOT_GUARD_PREFLIGHT: "boot:guard-preflight",

  /** `resolveAvailablePort(desiredPort, ...)` — port probe (may be slow on
   *  Windows due to TIME_WAIT; Phase 0 already added retry). */
  BOOT_RESOLVE_PORT: "boot:resolve-port",

  /** `createHMRServer(port, options?)` — Bun.serve + WebSocket + replay
   *  buffer setup. Phase 7.0.R4 added Origin allowlist + rate limit. */
  BOOT_HMR_SERVER: "boot:hmr-server",

  /** `startServer(manifest, ...)` — Bun.serve for the actual app. */
  BOOT_START_SERVER: "boot:start-server",

  /** `watchFSRoutes(...)` — chokidar watcher for spec/slots + app/ routes.
   *  Phase 7.1.A may not be able to remove this; it tracks new-route
   *  creation which `_doBuild` does not. */
  BOOT_WATCH_FS_ROUTES: "boot:watch-fs-routes",

  // ─── Phase 7.2 ─────────────────────────────────────────────────────────

  /** Tier 2 vendor shim disk-cache hit — all 4 shim outputs loaded from
   *  `.mandu/vendor-cache/` instead of rebuilt. Target: >95% on warm dev. */
  VENDOR_CACHE_HIT: "vendor:cache-hit",

  /** Tier 2 miss — any reason (no manifest / version mismatch / tamper /
   *  first boot). Full `buildVendorShims` runs. */
  VENDOR_CACHE_MISS: "vendor:cache-miss",

  /** Tier 2 cache write — after a successful rebuild, persist to disk.
   *  Only fires on miss paths. */
  VENDOR_CACHE_WRITE: "vendor:cache-write",

  /** HDR (Hot Data Revalidation) — slot change triggered a loader
   *  refetch without a React tree remount. Measures WS broadcast →
   *  client loader settled → props applied. Target: ≤ 150 ms P95. */
  HDR_REFETCH: "hdr:refetch",

  // ─── Phase 7.3 ─────────────────────────────────────────────────────────

  /** JIT pre-warm — `mandu dev` boot kicks off fire-and-forget imports
   *  of the hot SSR modules (react, react-dom, react-dom/server) so
   *  Bun's JITTier compiler has them ready before the user's first edit.
   *
   *  This marker measures the prewarm Promise's total wall-clock from
   *  boot-start to all `import()` settling — it is NOT on the critical
   *  path to "ready" (see `startPrewarmIdle`), so values here are
   *  informational for benchmarks only. Phase 7.2 F observed first-iter
   *  cold +41 ms vs warm steady-state; the goal is to absorb that into
   *  prewarm before the user hits a file save. */
  JIT_PREWARM: "boot:jit-prewarm",

  /** Phase 11 C — Deep-path JIT prewarm extension. Phase 7.3 A closed the
   *  first-iter gap from 41 ms to 25 ms by prewarming the React hot set;
   *  R0.3 diagnostics traced the remaining ~15 ms to the
   *  `registerManifestHandlers` deep-path (cli `util/handlers` +
   *  `util/bun` bundledImport + `@mandujs/core/bundler/safe-build`
   *  internals) which only execute on the FIRST SSR reload. This marker
   *  measures the settling time of the deep-import Promise — still
   *  fire-and-forget, still NOT on the critical path, so values are
   *  informational only. Target: first-iter ≤ 15 ms (hard) / ≤ 20 ms
   *  (soft). See `packages/cli/src/util/jit-prewarm.ts`. */
  JIT_PREWARM_DEEP: "boot:jit-prewarm-deep",

  /** API route handler reload (`handleAPIChange`) — `.route.ts` /
   *  `.route.tsx` change. Symmetric to `SSR_HANDLER_RELOAD` for page /
   *  layout reloads. Phase 7.2 §7.4 flagged that `handleAPIChange` was
   *  missing a top-level `withPerf()` wrap so Agent D's MANDU_PERF=1
   *  trace couldn't attribute API reload walltime.
   *
   *  Semantically API reloads are a subset of "route handler reload"
   *  (`SSR_HANDLER_RELOAD`), but a distinct marker lets benchmark scripts
   *  separate page vs API reload populations when computing P95. */
  API_HANDLER_RELOAD: "api:handler-reload",
} as const;

/**
 * Union of all marker names — useful when a function accepts an arbitrary
 * marker as a parameter and you want compile-time exhaustiveness.
 */
export type HMRPerfMarker = (typeof HMR_PERF)[keyof typeof HMR_PERF];

/**
 * Human-readable target thresholds. Source of truth for Agent F's hard
 * assertion pass/fail logic. Values in milliseconds.
 */
export const HMR_PERF_TARGETS = {
  /** Cold dev start (`mandu dev` → "ready" log). */
  COLD_START_MS: 500,

  /** Island-only rebuild P95, measured on REBUILD_TOTAL. */
  ISLAND_REBUILD_P95_MS: 50,

  /** SSR page rebuild P95, measured on REBUILD_TOTAL when kind === "ssr-only". */
  SSR_REBUILD_P95_MS: 200,

  /** Common-dir rebuild P95 (fan-out across multiple islands/SSR modules). */
  COMMON_DIR_REBUILD_P95_MS: 400,

  /** CSS-only rebuild P95. */
  CSS_REBUILD_P95_MS: 100,
} as const;
