/** Connector config tools — inspect and configure installed connectors (the
 *  external-system tool bundles: GitLab, Jenkins, Mantis, …). Installing comes
 *  from the marketplace (forge_marketplace_install); this is the post-install
 *  config surface: see settings + status, set settings, enable/disable, test.
 *
 *  Secret fields are stored encrypted at rest; this tool masks them on display
 *  (only "set"/"unset") and relies on the store to encrypt any secret values it
 *  writes. In-process lib calls. */

import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import {
  listInstalledConnectors, getInstalledConnector,
  setConnectorConfig, setConnectorEnabled,
} from '@/lib/connectors/registry';
import { runConnectorTest } from '@/lib/connectors/test-runner';
import { text, fail, guard, connectorFieldStatus } from './_shared';

export function registerConnectorTools(server: McpServer): void {
  server.tool(
    'forge_list_connectors',
    'List installed connectors (external-system tool bundles) and their enabled state. Pass id for one connector\'s settings schema + which fields are set/missing (secret values are masked). Configure with forge_configure_connector.',
    { id: z.string().optional().describe('A connector id for its settings detail') },
    (params) => guard(() => {
      if (params.id) {
        const inst = getInstalledConnector(params.id);
        if (!inst) return fail(`Connector not installed: ${params.id}. Find one with forge_marketplace_search kind="connector".`);
        const def = inst.definition;
        const lines = [
          `Connector: ${def.name} (${def.id}) [${inst.enabled ? 'enabled' : 'disabled'}] v${inst.installed_version}`,
        ];
        const fields = Object.entries(def.settings || {});
        if (fields.length) {
          lines.push('Settings:');
          for (const [k, f] of fields) lines.push(`  • ${k} [${f.type}${f.required ? ', required' : ''}] ${connectorFieldStatus(f, inst.config[k])}`);
        } else {
          lines.push('Settings: none.');
        }
        lines.push(`Configure: forge_configure_connector id="${def.id}" settings={…} enable=true test=true.`);
        return text(lines.join('\n'));
      }
      const all = listInstalledConnectors();
      if (!all.length) return text('No connectors installed. Find one with forge_marketplace_search kind="connector", then forge_marketplace_install.');
      const lines = all.map((c) => `• ${c.definition.id} (${c.definition.name}) [${c.enabled ? 'enabled' : 'disabled'}] v${c.installed_version}`);
      return text(`${all.length} connector(s):\n${lines.join('\n')}\n\nDetail: forge_list_connectors id="…".`);
    }),
  );

  server.tool(
    'forge_configure_connector',
    'Configure an installed connector: set one or more settings (secret fields are encrypted at rest), enable/disable it, and/or run its connection test. Provide at least one of settings, enable, or test.',
    {
      id: z.string().describe('Connector id (from forge_list_connectors)'),
      settings: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional()
        .describe('Field → value to set (merged over current config). See the schema via forge_list_connectors id=…'),
      enable: z.boolean().optional().describe('Enable (true) or disable (false) the connector'),
      test: z.boolean().optional().describe('Run the connector\'s connection test after applying changes'),
    },
    (params) => guard(async () => {
      const inst = getInstalledConnector(params.id);
      if (!inst) return fail(`Connector not installed: ${params.id}.`);
      const hasSettings = params.settings && Object.keys(params.settings).length > 0;
      if (!hasSettings && params.enable === undefined && !params.test) {
        return fail('Nothing to do — provide settings, enable, and/or test.');
      }
      const done: string[] = [];
      if (hasSettings) {
        setConnectorConfig(params.id, { ...inst.config, ...params.settings });
        done.push(`updated ${Object.keys(params.settings!).join(', ')}`);
      }
      if (params.enable !== undefined) {
        setConnectorEnabled(params.id, params.enable);
        done.push(params.enable ? 'enabled' : 'disabled');
      }
      let testLine = '';
      if (params.test) {
        const r = await runConnectorTest(params.id);
        testLine = `\nTest: ${r.ok ? 'OK' : `FAILED — ${r.error || 'unknown error'}`}`;
      }
      return text(`${inst.definition.name}: ${done.join('; ') || 'no changes'}.${testLine}`);
    }),
  );
}
