// @lifecycle canonical - Gate resource handler for MCP resources protocol.
/**
 * Gate Resources Handler
 *
 * Registers MCP resources for token-efficient gate discovery and guidance retrieval.
 *
 * URI Patterns:
 * - resource://gate/           → List all gates (minimal metadata)
 * - resource://gate/{id}       → Gate definition + guidance content
 * - resource://gate/{id}/guidance → Raw guidance.md content only
 */

import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';

import { ResourceNotFoundError, RESOURCE_URI_PATTERNS } from '../types.js';

import type { GateResourceMetadata, ResourceDependencies } from '../types.js';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import type { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';

/**
 * Build resource URI from pattern and optional ID
 * Patterns already include the full URI scheme (resource://...)
 */
function buildUri(pattern: string, id?: string): string {
  if (id !== undefined && id !== '') {
    return pattern.replace('{id}', id);
  }
  return pattern;
}

/**
 * Register gate-related MCP resources.
 *
 * Resources read from the gateManager at request time to ensure
 * hot-reload compatibility - changes are visible immediately.
 */
export function registerGateResources(server: McpServer, dependencies: ResourceDependencies): void {
  const { logger, gateManager } = dependencies;

  if (gateManager === undefined) {
    logger.warn('[GateResources] GateManager not available, skipping registration');
    return;
  }

  // Resource: List all gates (minimal metadata for token efficiency)
  server.registerResource(
    'gates',
    new ResourceTemplate(RESOURCE_URI_PATTERNS.GATE_LIST, {
      list: async () => {
        const guides = gateManager.list(false); // Include disabled gates
        logger.debug(`[GateResources] Listing ${guides.length} gates`);

        const resources: GateResourceMetadata[] = guides.map((g) => ({
          uri: buildUri(RESOURCE_URI_PATTERNS.GATE_ITEM, g.gateId),
          name: g.gateId,
          title: g.name,
          description: g.description.slice(0, 80),
          mimeType: 'text/markdown',
          type: g.type,
          enabled: true, // All guides from list are registered
          severity: g.severity,
        }));

        return { resources };
      },
    }),
    {
      description: 'List of all available gates with minimal metadata',
      mimeType: 'text/plain',
    },
    async (): Promise<ReadResourceResult> => {
      // When reading the list resource itself, return compact text format
      // Format: id: name (type) - 4x more token-efficient than JSON
      const guides = gateManager.list(false);
      const lines = guides.map((g) => `${g.gateId}: ${g.name} (${g.type})`);

      return {
        contents: [
          {
            uri: buildUri(RESOURCE_URI_PATTERNS.GATE_LIST),
            mimeType: 'text/plain',
            text: `Gates (${guides.length}):\n${lines.join('\n')}`,
          },
        ],
      };
    }
  );

  // Resource: Individual gate with full definition and guidance
  server.registerResource(
    'gate',
    new ResourceTemplate(RESOURCE_URI_PATTERNS.GATE_ITEM, {
      list: undefined, // Individual items discovered via list resource
    }),
    {
      description: 'Individual gate with definition and guidance content',
      mimeType: 'text/markdown',
    },
    async (uri, variables): Promise<ReadResourceResult> => {
      const id = variables['id'] as string;

      const guide = gateManager.get(id);

      if (guide === undefined) {
        throw new ResourceNotFoundError('Gate', id);
      }

      logger.debug(`[GateResources] Reading gate: ${id}`);

      // Build full gate content with metadata header
      const content = buildGateContent(guide);

      return {
        contents: [
          {
            uri: uri.toString(),
            mimeType: 'text/markdown',
            text: content,
          },
        ],
      };
    }
  );

  // Resource: Raw guidance content only (for minimal token usage)
  server.registerResource(
    'gate-guidance',
    new ResourceTemplate(RESOURCE_URI_PATTERNS.GATE_GUIDANCE, {
      list: undefined, // Discovered via gate/{id} resource
    }),
    {
      description: 'Raw gate guidance content only',
      mimeType: 'text/markdown',
    },
    async (uri, variables): Promise<ReadResourceResult> => {
      const id = variables['id'] as string;

      const guide = gateManager.get(id);

      if (guide === undefined) {
        throw new ResourceNotFoundError('Gate', id);
      }

      logger.debug(`[GateResources] Reading guidance for: ${id}`);

      const guidance = guide.getGuidance();

      return {
        contents: [
          {
            uri: uri.toString(),
            mimeType: 'text/markdown',
            text: guidance !== '' ? guidance : '(No guidance content)',
          },
        ],
      };
    }
  );

  logger.info('[GateResources] Registered gate resources');
}

/**
 * Build formatted gate content with metadata header and guidance
 */
function buildGateContent(guide: {
  gateId: string;
  name: string;
  description: string;
  type: 'validation' | 'guidance';
  severity: 'critical' | 'high' | 'medium' | 'low';
  getGuidance(): string;
}): string {
  const lines: string[] = [];

  // Metadata header
  lines.push(`# ${guide.name}`);
  lines.push('');
  lines.push(`**ID:** \`${guide.gateId}\``);
  lines.push(`**Type:** ${guide.type}`);
  lines.push(`**Severity:** ${guide.severity}`);

  if (guide.description !== '') {
    lines.push('');
    lines.push(`> ${guide.description}`);
  }

  // Guidance content
  const guidance = guide.getGuidance();
  if (guidance !== '') {
    lines.push('');
    lines.push('## Guidance');
    lines.push('');
    lines.push(guidance);
  }

  return lines.join('\n');
}
