#!/usr/bin/env node
// ═══════════════════════════════════════════════════════════
// GooseFactory MCP Server
//
// 11 Tools · 6 Resources · 4 Prompts · MCP App Modal Hosting
//
// The brain that lets AI agents and humans interact with
// the factory conversationally.
//
// Transport: stdio (default) or SSE
// ═══════════════════════════════════════════════════════════

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

// Tools
import { registerTaskTools } from "./tools/tasks.js";
import { registerPipelineTools } from "./tools/pipelines.js";
import { registerOperationsTools } from "./tools/operations.js";
import { registerReviewTools } from "./tools/review.js";

// Resources
import { registerDashboardResources } from "./resources/dashboard.js";
import { registerPipelineResources } from "./resources/pipelines.js";
import { registerConfigResources } from "./resources/config.js";

// Prompts
import { registerReviewServerPrompt } from "./prompts/review-server.js";
import { registerNeedsAttentionPrompt } from "./prompts/needs-attention.js";
import { registerDeployChecklistPrompt } from "./prompts/deploy-checklist.js";
import { registerRetrospectivePrompt } from "./prompts/retrospective.js";

// ═══════════════════════════════════════
// Server initialization
// ═══════════════════════════════════════

const server = new McpServer(
  {
    name: "goosefactory",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
      resources: {},
      prompts: {},
    },
  },
);

// ═══════════════════════════════════════
// Register all tools (11 total)
// ═══════════════════════════════════════

// Tasks: get_pending, approve, reject (3)
registerTaskTools(server);

// Pipelines: status, advance, create, search (4)
registerPipelineTools(server);

// Operations: assign_priority, get_blockers, run_tests, deploy (4)
registerOperationsTools(server);

// Review: request_review — MCP App modal trigger (1 — bonus tool)
registerReviewTools(server);

// ═══════════════════════════════════════
// Register all resources (6 total)
// ═══════════════════════════════════════

// factory://dashboard/summary
registerDashboardResources(server);

// factory://pipelines/{id}/state, factory://servers/{name}/status,
// factory://pipelines/{id}/test-results, factory://pipelines/{id}/build-logs
registerPipelineResources(server);

// factory://config/templates
registerConfigResources(server);

// ═══════════════════════════════════════
// Register all prompts (4 total)
// ═══════════════════════════════════════

registerReviewServerPrompt(server);
registerNeedsAttentionPrompt(server);
registerDeployChecklistPrompt(server);
registerRetrospectivePrompt(server);

// ═══════════════════════════════════════
// Transport setup
// ═══════════════════════════════════════

const transport = process.env.FACTORY_MCP_TRANSPORT || "stdio";

async function main(): Promise<void> {
  if (transport === "stdio") {
    const stdioTransport = new StdioServerTransport();
    await server.connect(stdioTransport);
    console.error("[GooseFactory MCP] Server started (stdio transport)");
    console.error("[GooseFactory MCP] 12 tools, 6 resources, 4 prompts registered");
    console.error(`[GooseFactory MCP] API: ${process.env.FACTORY_API_URL || "http://localhost:4000/v1"}`);
  } else if (transport === "sse") {
    // SSE transport for HTTP-based connections
    // The MCP SDK provides SSEServerTransport for this
    const { SSEServerTransport } = await import("@modelcontextprotocol/sdk/server/sse.js");
    const http = await import("node:http");

    const PORT = parseInt(process.env.FACTORY_MCP_PORT || "3001", 10);

    // Track active SSE transports
    const transports: Map<string, InstanceType<typeof SSEServerTransport>> = new Map();

    const httpServer = http.createServer(async (req, res) => {
      const url = new URL(req.url || "/", `http://localhost:${PORT}`);

      // CORS headers
      res.setHeader("Access-Control-Allow-Origin", "*");
      res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
      res.setHeader("Access-Control-Allow-Headers", "Content-Type");

      if (req.method === "OPTIONS") {
        res.writeHead(204);
        res.end();
        return;
      }

      if (url.pathname === "/sse" && req.method === "GET") {
        // New SSE connection
        const sseTransport = new SSEServerTransport("/messages", res);
        transports.set(sseTransport.sessionId, sseTransport);
        
        res.on("close", () => {
          transports.delete(sseTransport.sessionId);
        });

        await server.connect(sseTransport);
        return;
      }

      if (url.pathname === "/messages" && req.method === "POST") {
        // Handle incoming messages for SSE transport
        const sessionId = url.searchParams.get("sessionId");
        if (sessionId && transports.has(sessionId)) {
          const transport = transports.get(sessionId)!;
          await transport.handlePostMessage(req, res);
          return;
        }
        res.writeHead(404);
        res.end("Session not found");
        return;
      }

      // Health check
      if (url.pathname === "/health") {
        res.writeHead(200, { "Content-Type": "application/json" });
        res.end(JSON.stringify({ status: "ok", server: "goosefactory-mcp", version: "1.0.0" }));
        return;
      }

      res.writeHead(404);
      res.end("Not found");
    });

    httpServer.listen(PORT, () => {
      console.error(`[GooseFactory MCP] Server started (SSE transport) on port ${PORT}`);
      console.error("[GooseFactory MCP] 12 tools, 6 resources, 4 prompts registered");
      console.error(`[GooseFactory MCP] SSE endpoint: http://localhost:${PORT}/sse`);
      console.error(`[GooseFactory MCP] API: ${process.env.FACTORY_API_URL || "http://localhost:4000/v1"}`);
    });
  } else {
    console.error(`[GooseFactory MCP] Unknown transport: ${transport}`);
    console.error("[GooseFactory MCP] Set FACTORY_MCP_TRANSPORT to 'stdio' or 'sse'");
    process.exit(1);
  }
}

main().catch((err) => {
  console.error("[GooseFactory MCP] Fatal error:", err);
  process.exit(1);
});
