/**
 * Default Plugin — composes gate + content-pipeline.
 *
 * This is the standard proxy model for mcpctl projects:
 * - Gated sessions with prompt selection
 * - Content transformation pipeline (paginate, section-split, etc.)
 *
 * When resolved through the plugin loader with inheritance, it inherits
 * all hooks from both parents. Since gate and content-pipeline don't
 * overlap on hooks, no conflicts arise.
 */
import type { ProxyModelPlugin } from '../plugin.js';
import { createGatePlugin, type GatePluginConfig } from './gate.js';
import { createContentPipelinePlugin } from './content-pipeline.js';

export interface DefaultPluginConfig extends GatePluginConfig {}

/**
 * Create the default plugin that merges gate + content-pipeline.
 *
 * Instead of relying on the loader's inheritance resolution (which needs
 * all plugins registered first), we directly compose the two plugins here.
 */
export function createDefaultPlugin(config: DefaultPluginConfig = {}): ProxyModelPlugin {
  const gate = createGatePlugin(config);
  const pipeline = createContentPipelinePlugin();

  const plugin: ProxyModelPlugin = {
    name: 'default',
    description: 'Default proxy model: gated sessions with paginated content.',
    extends: ['gate', 'content-pipeline'] as const,

    // Lifecycle: chain both
    async onSessionCreate(ctx) {
      if (gate.onSessionCreate) await gate.onSessionCreate(ctx);
      if (pipeline.onSessionCreate) await pipeline.onSessionCreate(ctx);
    },

    async onSessionDestroy(ctx) {
      if (gate.onSessionDestroy) await gate.onSessionDestroy(ctx);
      if (pipeline.onSessionDestroy) await pipeline.onSessionDestroy(ctx);
    },

    // Tool call before: gate intercept first, then content-pipeline section drill-down
    async onToolCallBefore(toolName, args, request, ctx) {
      if (gate.onToolCallBefore) {
        const intercepted = await gate.onToolCallBefore(toolName, args, request, ctx);
        if (intercepted) return intercepted;
      }
      if (pipeline.onToolCallBefore) {
        const intercepted = await pipeline.onToolCallBefore(toolName, args, request, ctx);
        if (intercepted) return intercepted;
      }
      return null;
    },
  };

  // Conditionally add optional hooks to satisfy exactOptionalPropertyTypes
  if (gate.onInitialize) {
    plugin.onInitialize = gate.onInitialize.bind(gate);
  }
  if (gate.onToolsList) {
    plugin.onToolsList = gate.onToolsList.bind(gate);
  }
  if (pipeline.onToolCallAfter) {
    plugin.onToolCallAfter = pipeline.onToolCallAfter.bind(pipeline);
  }

  return plugin;
}
