"use strict";

/**
 * OpenClaw MCP Tool Server.
 *
 * Provides a simple MCP-compatible tool server for knowledge base access.
 * When run with `openclaw-mcp serve`, starts an HTTP server that responds
 * to JSON-RPC 2.0 requests.
 */

const http = require("http");

const TOOLS = [
  {
    name: "search_knowledge",
    description:
      "Search the OpenClaw knowledge base for documentation, guides, and troubleshooting info.",
    inputSchema: {
      type: "object",
      properties: {
        query: {
          type: "string",
          description: "Search query",
        },
      },
      required: ["query"],
    },
  },
  {
    name: "get_config_reference",
    description:
      "Get the configuration reference for a specific OpenClaw config field.",
    inputSchema: {
      type: "object",
      properties: {
        field: {
          type: "string",
          description: "Config field path (e.g. 'server.port', 'gateway.rateLimit')",
        },
      },
      required: ["field"],
    },
  },
  {
    name: "get_troubleshooting",
    description:
      "Get troubleshooting steps for a specific error or issue.",
    inputSchema: {
      type: "object",
      properties: {
        issue: {
          type: "string",
          description: "Description of the issue or error message",
        },
      },
      required: ["issue"],
    },
  },
];

function handleRpc(body) {
  const { method, params, id } = body;

  switch (method) {
    case "initialize":
      return {
        jsonrpc: "2.0",
        id,
        result: {
          protocolVersion: "2024-11-05",
          capabilities: { tools: {} },
          serverInfo: {
            name: "openclaw-mcp-tools",
            version: "0.1.0",
          },
        },
      };

    case "tools/list":
      return {
        jsonrpc: "2.0",
        id,
        result: { tools: TOOLS },
      };

    case "tools/call": {
      const toolName = params?.name || "";
      const toolArgs = params?.arguments || {};
      let content;

      switch (toolName) {
        case "search_knowledge":
          content = `Knowledge base results for "${toolArgs.query}": ` +
            "Refer to the OpenClaw documentation at https://docs.easyclaw.help for detailed guides.";
          break;
        case "get_config_reference":
          content = `Config reference for "${toolArgs.field}": ` +
            "See /etc/openclaw/config.json for the full configuration schema.";
          break;
        case "get_troubleshooting":
          content = `Troubleshooting "${toolArgs.issue}": ` +
            "Check logs at /var/log/openclaw/, verify config with 'openclaw config validate', " +
            "and ensure services are running with 'systemctl status openclaw'.";
          break;
        default:
          return {
            jsonrpc: "2.0",
            id,
            error: { code: -32601, message: `Unknown tool: ${toolName}` },
          };
      }

      return {
        jsonrpc: "2.0",
        id,
        result: {
          content: [{ type: "text", text: content }],
        },
      };
    }

    case "notifications/initialized":
      return null; // No response for notifications

    default:
      return {
        jsonrpc: "2.0",
        id,
        error: { code: -32601, message: `Method not found: ${method}` },
      };
  }
}

function serve(args) {
  const port = parseInt(args.find((a) => a.startsWith("--port="))?.split("=")[1] || "3300");

  const server = http.createServer((req, res) => {
    if (req.method === "POST" && req.url === "/mcp") {
      let body = "";
      req.on("data", (chunk) => (body += chunk));
      req.on("end", () => {
        try {
          const parsed = JSON.parse(body);
          const result = handleRpc(parsed);
          if (result === null) {
            res.writeHead(204);
            res.end();
          } else {
            res.writeHead(200, { "Content-Type": "application/json" });
            res.end(JSON.stringify(result));
          }
        } catch (err) {
          res.writeHead(400, { "Content-Type": "application/json" });
          res.end(
            JSON.stringify({
              jsonrpc: "2.0",
              error: { code: -32700, message: "Parse error" },
            })
          );
        }
      });
    } else {
      res.writeHead(404);
      res.end("Not Found");
    }
  });

  server.listen(port, "0.0.0.0", () => {
    console.log(`OpenClaw MCP Tool Server listening on port ${port}`);
  });
}

function list(args) {
  console.log("Available MCP Tools:");
  console.log("");
  for (const tool of TOOLS) {
    console.log(`  ${tool.name}`);
    console.log(`    ${tool.description}`);
    console.log("");
  }
  console.log(`Total: ${TOOLS.length} tool(s)`);
}

module.exports = { serve, list };
