import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import {
  ListResourcesRequestSchema,
  ReadResourceRequestSchema,
  ListToolsRequestSchema,
  CallToolRequestSchema
} from "@modelcontextprotocol/sdk/types.js";
import { HybridResourcesProvider } from "../services/HybridResourcesProvider.js";
import { CLIProxyService } from "../services/CLIProxyService.js";
import { EntityModuleService } from "../services/EntityModuleService.js";
import { EventEmitter } from "../events/EventEmitter.js";
class MCPServerController {
  server;
  config;
  resourcesProvider;
  cliProxy;
  entityModuleService;
  eventEmitter;
  constructor(config) {
    this.config = config;
    this.eventEmitter = new EventEmitter();
    this.server = new Server({
      name: "specverse-dynamic-cli",
      version: "1.0.0"
    }, {
      capabilities: {
        resources: {},
        tools: {}
      }
    });
    this.resourcesProvider = new HybridResourcesProvider({
      mode: "auto",
      resourcesPath: config.resources_path
    });
    this.cliProxy = new CLIProxyService();
    this.entityModuleService = new EntityModuleService();
    this.setupHandlers();
  }
  async listResources() {
    try {
      const startTime = Date.now();
      const resources = await this.resourcesProvider.listResources();
      if (this.entityModuleService.isAvailable()) {
        resources.push(...this.entityModuleService.generateResources());
      }
      this.eventEmitter.emit("resource-requested", {
        uri: "LIST_ALL",
        requestTime: /* @__PURE__ */ new Date()
      });
      if (this.config.logging && this.config.mode !== "local" && process.env.MCP_DEBUG) {
        console.error(`Listed ${resources.length} resources in ${Date.now() - startTime}ms`);
      }
      return resources;
    } catch (error) {
      this.eventEmitter.emit("error-occurred", {
        operation: "listResources",
        error: error instanceof Error ? error.message : String(error)
      });
      throw error;
    }
  }
  async readResource(uri) {
    try {
      const startTime = Date.now();
      if (uri.startsWith("specverse://entities/") && this.entityModuleService.isAvailable()) {
        const entityResources = this.entityModuleService.generateResources();
        const resource2 = entityResources.find((r) => r.uri === uri);
        if (resource2) {
          this.eventEmitter.emit("resource-requested", { uri, requestTime: /* @__PURE__ */ new Date() });
          return resource2;
        }
      }
      const content = await this.resourcesProvider.getResourceContent(uri);
      const resources = await this.resourcesProvider.listResources();
      const resource = resources.find((r) => r.uri === uri);
      if (!resource) {
        throw new Error(`Resource not found: ${uri}`);
      }
      this.eventEmitter.emit("resource-requested", {
        uri,
        requestTime: /* @__PURE__ */ new Date()
      });
      if (this.config.logging && this.config.mode !== "local" && process.env.MCP_DEBUG) {
        console.error(`Read resource ${uri} in ${Date.now() - startTime}ms`);
      }
      return {
        ...resource,
        content
      };
    } catch (error) {
      this.eventEmitter.emit("error-occurred", {
        operation: "readResource",
        error: error instanceof Error ? error.message : String(error),
        context: { uri }
      });
      throw error;
    }
  }
  setupHandlers() {
    this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
      const resources = await this.listResources();
      return { resources };
    });
    this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
      const resource = await this.readResource(request.params.uri);
      return {
        contents: [{
          uri: resource.uri,
          mimeType: resource.mimeType,
          text: resource.content
        }]
      };
    });
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      let dynamicCliTools = [];
      try {
        dynamicCliTools = await this.cliProxy.generateMCPTools();
        if (this.config.logging && this.config.mode !== "local" && process.env.MCP_DEBUG) {
          console.error(`\u{1F527} Generated ${dynamicCliTools.length} dynamic CLI tools`);
        }
      } catch (error) {
        if (this.config.logging && process.env.MCP_DEBUG) {
          console.error("\u26A0\uFE0F Failed to generate dynamic CLI tools:", error);
        }
      }
      if (this.entityModuleService.isAvailable()) {
        dynamicCliTools.push(...this.entityModuleService.generateTools());
      }
      return { tools: dynamicCliTools };
    });
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      try {
        const { name, arguments: args } = request.params;
        const entityToolNames = ["specverse_expand_constraint", "specverse_list_conventions", "specverse_entity_info"];
        if (entityToolNames.includes(name) && this.entityModuleService.isAvailable()) {
          return await this.entityModuleService.executeTool(name, args || {});
        }
        if (name.startsWith("specverse_")) {
          const result = await this.cliProxy.executeCommand(name, args || {});
          return { content: result.content };
        } else {
          return {
            content: [{
              type: "text",
              text: `Error: Unknown tool '${name}'. Only dynamic CLI tools (prefixed with 'specverse_') are supported.`
            }]
          };
        }
      } catch (error) {
        return {
          content: [{
            type: "text",
            text: `Error in tool handler: ${error instanceof Error ? error.message : String(error)}`
          }]
        };
      }
    });
  }
  /**
   * Start the MCP server
   */
  async start() {
    try {
      await this.resourcesProvider.initializeResources();
      const entityAvailable = await this.entityModuleService.initialize();
      if (this.config.logging && process.env.MCP_DEBUG) {
        if (entityAvailable) {
          const modules = this.entityModuleService.getEntityModules();
          console.error(`\u{1F9E9} Entity modules loaded: ${modules.length} modules, ${modules.reduce((s, m) => s + m.inferenceRuleCount, 0)} rules`);
        } else {
          console.error("\u26A0\uFE0F Entity modules not available in this deployment");
        }
      }
      this.eventEmitter.emit("server-started", {
        serverName: "SpecVerse Dynamic CLI",
        mode: this.config.mode,
        timestamp: /* @__PURE__ */ new Date(),
        featuresEnabled: this.config.features,
        pid: process.pid
      });
      if (this.config.logging && process.env.MCP_DEBUG) {
        const mode = this.config.mode || "local";
        const resourceCount = this.resourcesProvider.getCachedResourceCount();
        console.error(`\u{1F680} SpecVerse MCP Server started in ${mode} mode`);
        console.error(`\u{1F4DA} Loaded ${resourceCount} resources`);
        console.error(`\u{1F527} Dynamic CLI integration enabled - all tools from CLI`);
      }
    } catch (error) {
      this.eventEmitter.emit("error-occurred", {
        operation: "start",
        error: error instanceof Error ? error.message : String(error)
      });
      throw error;
    }
  }
  /**
   * Stop the MCP server
   */
  async stop() {
    try {
      await this.server.close();
      if (this.config.logging && process.env.MCP_DEBUG) {
        console.error("\u{1F6D1} SpecVerse MCP Server stopped");
      }
    } catch (error) {
      this.eventEmitter.emit("error-occurred", {
        operation: "stop",
        error: error instanceof Error ? error.message : String(error)
      });
      throw error;
    }
  }
  // Methods expected by the main server
  getEventEmitter() {
    return this.eventEmitter;
  }
  async initialize() {
    await this.start();
  }
  getServer() {
    return this.server;
  }
  getMetrics() {
    return {
      resourceCount: this.resourcesProvider.getCachedResourceCount(),
      cliIntegration: true
    };
  }
}
export {
  MCPServerController
};
