import callToolRequestHandler from './call-tool-request.handler';
import completeRequestHandler from './complete-request.handler';
import getPromptRequestHandler from './get-prompt-request.handler';
import initializeRequestHandler from './initialize-request.handler';
import initializedNotificationHandler from './Initialized-notification.hanlder';
import listPromptsRequestHandler from './list-prompts-request.handler';
import listResourceTemplatesRequestHandler from './list-resource-templates-request.handler';
import listResourcesRequestHandler from './list-resources-request.handler';
import listToolsRequestHandler from './list-tools-request.handler';
import loggingSetLevelRequestHandler from './logging-set-level-request.handler';
import { type McpHandlerOptions } from './mcp-handlers.types';
import readResourceRequestHandler from './read-resource-request.handler';
import rootsListChangedNotificationHandler from './roots-list-changed-notification.handler';
import skillsListRequestHandler from './skills-list-request.handler';
import skillsLoadRequestHandler from './skills-load-request.handler';
import skillsSearchRequestHandler from './skills-search-request.handler';
import subscribeRequestHandler from './subscribe-request.handler';
import tasksCancelRequestHandler from './tasks-cancel-request.handler';
import tasksGetRequestHandler from './tasks-get-request.handler';
import tasksListRequestHandler from './tasks-list-request.handler';
import tasksResultRequestHandler from './tasks-result-request.handler';
import unsubscribeRequestHandler from './unsubscribe-request.handler';

export function createMcpHandlers(options: McpHandlerOptions) {
  // List handlers are ALWAYS registered, independent of capability advertisement.
  // The underlying flows (ToolsListFlow / ResourcesListFlow / PromptsListFlow,
  // registered on the scope at boot regardless of metadata) return empty arrays
  // when the registry is empty, matching the MCP spec contract for list methods.
  //
  // Issue #407: previously these handlers were gated on `serverOptions.capabilities.{tools|resources|prompts}`,
  // which is itself gated on `registry.hasAny()`. Empty registries therefore
  // produced no list handler and `mcp.tools.list()` / `resources.list()` /
  // `prompts.list()` failed with JSON-RPC -32601 "Method not found".
  //
  // Capability advertisement (and gating of call/read/get/subscribe/unsubscribe)
  // remains decoupled — clients that speculatively probe list endpoints get a
  // clean empty result; clients that follow capability advertisement strictly
  // are still informed about which entity types are actually available.
  const listHandlers = [
    listToolsRequestHandler(options),
    listResourcesRequestHandler(options),
    listResourceTemplatesRequestHandler(options),
    listPromptsRequestHandler(options),
  ];

  const toolsHandler = options.serverOptions?.capabilities?.tools ? [callToolRequestHandler(options)] : [];
  const resourcesHandler = options.serverOptions?.capabilities?.resources
    ? [readResourceRequestHandler(options), subscribeRequestHandler(options), unsubscribeRequestHandler(options)]
    : [];

  const promptsHandler = options.serverOptions?.capabilities?.prompts ? [getPromptRequestHandler(options)] : [];

  // Completion handler is available when there are actual prompts or
  // resources to complete against, AND the `completions` capability is
  // advertised. Per MCP spec, `completion/complete` supports both
  // `ref/prompt` and `ref/resource`. Issue #407: since `getCapabilities()`
  // for prompts/resources is now always-on (so the SDK accepts the
  // always-registered list handlers), we can no longer use those flags as
  // a proxy for "there is anything to complete". Gate on the actual scope
  // registries' `hasAny()` instead.
  const hasPromptsOrResources = options.scope?.prompts?.hasAny() || options.scope?.resources?.hasAny();
  const completionHandler =
    hasPromptsOrResources && options.serverOptions?.capabilities?.completions ? [completeRequestHandler(options)] : [];

  // Logging handler is available when logging capability is enabled
  // Per MCP 2025-11-25 spec, servers MAY provide logging capability
  const loggingHandler = options.serverOptions?.capabilities?.logging ? [loggingSetLevelRequestHandler(options)] : [];

  // Skills handlers are available when skill registry has skills
  // Skills is a FrontMCP extension to MCP (custom methods: skills/search, skills/load, skills/list)
  const skillsHandler = options.scope?.skills?.hasAny()
    ? [skillsSearchRequestHandler(options), skillsLoadRequestHandler(options), skillsListRequestHandler(options)]
    : [];

  // Tasks handlers per MCP 2025-11-25 tasks spec. Only registered when the
  // `tasks` capability is advertised (driven by tool-level `execution.taskSupport`).
  const tasksHandler = (options.serverOptions?.capabilities as Record<string, unknown> | undefined)?.['tasks']
    ? [
        tasksGetRequestHandler(options),
        tasksResultRequestHandler(options),
        tasksCancelRequestHandler(options),
        tasksListRequestHandler(options),
      ]
    : [];

  return [
    // initializeRequestHandler reads `composeInstructions` from `options` so
    // the response reflects dynamic skill registrations made after boot.
    initializeRequestHandler(options),
    initializedNotificationHandler(options),
    rootsListChangedNotificationHandler(options),
    ...listHandlers,
    ...toolsHandler,
    ...resourcesHandler,
    ...promptsHandler,
    ...completionHandler,
    ...loggingHandler,
    ...skillsHandler,
    ...tasksHandler,
  ];
}

// export function hookMcpHandlers(gateway: FrontMcpInterface, handlers: McpHandler[]): McpHandler[] {
//   return handlers;
// }
