/**
 * Default stage handler registry.
 *
 * Maps built-in stage type names to their handler implementations.
 * Custom handlers can be registered by supplying a custom `IPipeline` implementation.
 */

import type {
  IActivationStrategy,
  SubAgentRegistry,
} from '@mcp-abap-adt/llm-agent';
import type { IStageHandler } from '../stage-handler.js';
import { AssembleHandler } from './assemble.js';
import { BuildToolQueryHandler } from './build-tool-query.js';
import { ClassifyHandler } from './classify.js';
import {
  CoordinatorHandler,
  type CoordinatorHandlerDeps,
} from './coordinator.js';
import { CoordinatorActivateHandler } from './coordinator-activate.js';
import {
  DagCoordinatorHandler,
  type DagCoordinatorHandlerDeps,
} from './dag-coordinator.js';
import { ExpandHandler } from './expand.js';
import { HistoryUpsertHandler } from './history-upsert.js';
import { RagQueryHandler } from './rag-query.js';
import { RerankHandler } from './rerank.js';
import { SkillSelectHandler } from './skill-select.js';
import { SubAgentHandler } from './subagent.js';
import { SummarizeHandler } from './summarize.js';
import { ToolLoopHandler } from './tool-loop.js';
import { ToolSelectHandler } from './tool-select.js';
import { TranslateHandler } from './translate.js';

export type StageHandlerRegistry = Map<string, IStageHandler>;

/**
 * Build the default handler registry with all built-in stage handlers.
 *
 * The registry maps stage type names (as used in YAML) to their handler
 * instances. All handlers are stateless — they read/write through the
 * {@link PipelineContext}.
 */
export interface BuildHandlerRegistryOptions {
  subAgents?: SubAgentRegistry;
  coordinator?: CoordinatorHandlerDeps;
  /**
   * DAG coordinator deps. When set, registers `DagCoordinatorHandler` under
   * the `coordinator` stage slot. Mutually exclusive with `coordinator` —
   * `dagCoordinator` takes precedence when both are supplied.
   */
  dagCoordinator?: DagCoordinatorHandlerDeps;
  /**
   * Pre-built stage handler to register under the `coordinator` slot.
   * Takes precedence over `dagCoordinator` and `coordinator` when all three
   * are supplied. Used by the 18.0 Stepper runtime: caller builds a
   * `StepperCoordinatorHandler` and passes it in directly.
   */
  stepperCoordinator?: IStageHandler;
  /**
   * Activation strategy used by the `coordinator-activate` runtime stage to
   * compute `ctx.coordinatorActive`. Required when `coordinator` is set —
   * without it, coordinator activation cannot honour runtime skill state.
   */
  coordinatorActivation?: IActivationStrategy;
}

export function buildDefaultHandlerRegistry(
  opts: BuildHandlerRegistryOptions = {},
): StageHandlerRegistry {
  const registry = new Map<string, IStageHandler>([
    ['classify', new ClassifyHandler()],
    ['summarize', new SummarizeHandler()],
    ['translate', new TranslateHandler()],
    ['expand', new ExpandHandler()],
    ['rag-query', new RagQueryHandler()],
    ['rerank', new RerankHandler()],
    ['skill-select', new SkillSelectHandler()],
    ['build-tool-query', new BuildToolQueryHandler()],
    ['tool-select', new ToolSelectHandler()],
    ['assemble', new AssembleHandler()],
    ['tool-loop', new ToolLoopHandler()],
    ['history-upsert', new HistoryUpsertHandler()],
  ]);
  if (opts.subAgents && opts.subAgents.size > 0) {
    registry.set('subagent', new SubAgentHandler(opts.subAgents));
  }
  if (opts.stepperCoordinator) {
    registry.set('coordinator', opts.stepperCoordinator);
  } else if (opts.dagCoordinator) {
    registry.set('coordinator', new DagCoordinatorHandler(opts.dagCoordinator));
  } else if (opts.coordinator) {
    registry.set('coordinator', new CoordinatorHandler(opts.coordinator));
  }
  if (opts.coordinatorActivation) {
    registry.set(
      'coordinator-activate',
      new CoordinatorActivateHandler(opts.coordinatorActivation),
    );
  }
  return registry;
}

export { summarizeAndStore } from './history-upsert.js';
export {
  AssembleHandler,
  BuildToolQueryHandler,
  ClassifyHandler,
  ExpandHandler,
  HistoryUpsertHandler,
  RagQueryHandler,
  RerankHandler,
  SkillSelectHandler,
  SummarizeHandler,
  ToolLoopHandler,
  ToolSelectHandler,
  TranslateHandler,
};
