/*
 * priority-forge-hub — integration factory
 *
 * Single entry point for hosts. Constructs:
 *   - a TeamMemorySyncReader  (read path: poll the active backend)
 *   - a blocker-emitter        (derive + emit cross-agent edges)
 *   - a subscriber             (write path: host EventEmitter → hub.write)
 * and wires them together. Returns a handle the host uses to access the
 * reader, force rederivation, or detach on shutdown.
 *
 * One process-level singleton is tracked so mcp-tools.ts can find the
 * currently-active integration without taking a circular dep on index.ts.
 */

import { createBlockerEmitter, BlockerEmitterHandle } from './blocker-emitter';
import { isMemoryPersistenceActive, loadMemoryHubConfig } from './config';
import { getOrchestrationHub } from './factory';
import { attachSubscriber, SubscriberHandle } from './subscriber';
import { TeamMemorySyncReader } from './sync-reader';
import { OrchestrationHub, TaskProvider } from './types';
import { EventEmitter } from 'events';

export interface MemoryHubIntegrationDeps {
  emitter: EventEmitter;
  taskProvider: TaskProvider;
}

export interface MemoryHubIntegrationHandle {
  reader: TeamMemorySyncReader;
  rederive(): Promise<void>;
  // Cross-forge orchestration plane. Always non-null; adapters that don't
  // support claim semantics (noop, xmem-today) return sentinel errors from
  // each method and have `supportsOrchestration: false`.
  orchestrationHub: OrchestrationHub;
  detach(): void;
}

let _current: MemoryHubIntegrationHandle | null = null;

export function createMemoryHubIntegration(
  deps: MemoryHubIntegrationDeps,
): MemoryHubIntegrationHandle {
  const reader = new TeamMemorySyncReader();
  const blockerEmitter: BlockerEmitterHandle = createBlockerEmitter({
    taskProvider: deps.taskProvider,
    reader,
  });
  reader.onAfterPoll(async () => {
    await blockerEmitter.rederive();
  });
  const subscription: SubscriberHandle = attachSubscriber({
    emitter: deps.emitter,
    rederive: () => blockerEmitter.rederive(),
  });
  if (isMemoryPersistenceActive()) {
    reader.start();
  }
  const handle: MemoryHubIntegrationHandle = {
    reader,
    rederive: () => blockerEmitter.rederive(),
    orchestrationHub: getOrchestrationHub(),
    detach() {
      subscription.detach();
      reader.stop();
      if (_current === handle) _current = null;
    },
  };
  _current = handle;
  return handle;
}

export function getCurrentIntegration(): MemoryHubIntegrationHandle | null {
  return _current;
}
