// import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
// import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
// import { z } from "zod";
// import { enumerateFields } from "./toolImplementations/graphqlschema";
// import { getFileContents, makeAsciiDirectoryStructure } from "./toolImplementations/renderFileTree";
// import { CallToolRequest, CallToolResult } from "@modelcontextprotocol/sdk/types";
// import { applyFileOps, FileOperationSchema } from "./toolImplementations/fileOps";
// import path from "path";
// import { apptileContextZodSchema } from "../../../utils";
// import { searchIcons } from "./toolImplementations/iconList";
// import axios from "axios";

// const server = new McpServer(
//   {
//     name: "filesystem-tools",
//     version: "1.0.0",
//   },
//   {
//     capabilities: {
//       tools: {}
//     }
//   }
// );

// server.tool(
//   "explore_shopify_graphql_schema", 
//   "Enumerate the fields for an object in the graphql schema inside the query field. Mutations are not available throught this tool. To get the entire set of top level fields in the queries section pass path as a blank string i.e. ''",
//   {
//     path: z.string().describe("A dot separated string specifying the field in the schema whose fields are to be enumerated. If a blank string is passed the top level of the schema will be enumerated."),
//     includeDescriptions: z.boolean().describe("Include the descriptions for the fields in the result"),
//     includeArgumentsInfo: z.boolean().describe("Include all available information about the arguments applicable to the fields being returned. Set this to true sparingly to save tokens.")
//   },
//   async (inputVars) => {
//     const result = await enumerateFields(inputVars.path, inputVars.includeDescriptions, inputVars.includeArgumentsInfo);
//     const response: CallToolResult = {
//       content: [{
//         type: "text",
//         text: JSON.stringify(result)
//       }]
//     };
//     return response;
//   }
// );

// // server.tool(
// //   "explore_directories",
// //   "Display the location of a set of files in the working directory of a plugin using ascii",
// //   {
// //     // The agent always passes ROOT, but the caller of the tool will overwrite it with the correct plugin root
// //     rootPath: z.string().describe("Path of the PLUGIN_ROOT directory. Should always be set to 'PLUGIN_ROOT'"),
// //     filePaths: z.array(z.string().describe("relative path")).describe("An array of relative paths within the PLUGIN_ROOT directory whose location should be visualized")
// //   },
// //   async (inputVars) => {
// //     const result = makeAsciiDirectoryStructure(inputVars.rootPath, inputVars.filePaths);
// //     return {
// //       content: [{
// //         type: "text",
// //         text: result
// //       }]
// //     };
// //   }
// // )

// server.tool(
//   "read_files_for_plugin",
//   "Get at a path relative to root directory of the plugin you are working on",
//   {
//     root_path: z.string().describe("name of the directory whose files are to be read. For the topmose accessible directory pass '.'. This takes a directory name and not a file name. All the files of a directory will be read and returned once its passed."),
//     apptile_context: apptileContextZodSchema
//   },
//   async (inputVars) => {
//     if (inputVars.apptile_context) {
//       const files = await getFileContents(path.resolve(inputVars.apptile_context.plugin_root, inputVars.root_path), []);
//       if (files.length === 0) {
//         return {
//           content: [{
//             type: "text",
//             text: "No files found!"
//           }]
//         }
//       } else {
//         const response: CallToolResult = {
//           content: []
//         };

//         for (let i = 0; i < files.length; ++i) {
//           // response.content.push({
//           //   type: "text",
//           //   text: "File: " + files[i].path
//           // });
//           const filePath = files[i].path;
//           const fileContents = files[i].content;

//           response.content.push({
//             type: "text",
//             text: filePath + '\n' + '```\n' + fileContents + '\n```'
//           })
//         }
//         return response;
//       }
//     } else {
//       throw new Error("Apptile context not provided!");
//     }
//   }
// );

// server.tool(
//   "apply_file_ops",
//   "Overwrite/Delete/Move a file using file operations",
//   { 
//     file_ops: z.array(FileOperationSchema),
//     apptile_context: z.object({
//       plugin_root: z.string()
//     }).nullable().describe("This should always be passed as null by the LLM. It will be set to the correct path by the tool.")
//   },
//   async (inputVars) => {
//     if (!inputVars.apptile_context?.plugin_root) {
//       throw new Error("Apptile context was not provided!");
//     }

//     let isLLMTryingToModifyWidgetJSX = false;
//     let file_paths_copy = [];
//     for (let i = 0; i < inputVars.file_ops.length; ++i) {
//       let filePath = inputVars.file_ops[i].path;
//       // if the llm tries to create source folder immediately inside the source folder
//       // then prevent it. It is actually trying to write files in the source
//       // folder. I have not been able to tune the system prompt to prevent it 
//       // from doing this from time to time.
//       if (filePath.startsWith("source/")) {
//         let numSlashes = 0;
//         for (let i = 0;  i < filePath.length; ++i) {
//           if (filePath[i] === "/") {
//             numSlashes++;
//           }
//         }
//         if (numSlashes === 1) {
//           filePath = filePath.substring("source/".length);
//         }
//       }
//       file_paths_copy.push(filePath);
//       inputVars.file_ops[i].path = path.resolve(
//         inputVars.apptile_context.plugin_root, 
//         filePath
//       );

//       if (inputVars.file_ops[i].path.endsWith("widget.jsx")) {
//         isLLMTryingToModifyWidgetJSX = true;
//         break;
//       }
//     }
//     // console.log("Finalized fileops: ", inputVars.file_ops);

//     if (isLLMTryingToModifyWidgetJSX) {
//       return {
//         content: [{
//           type: "text",
//           text: "Error: You cannot modify widget.jsx! This is a readonly file \
//           and your changes will be overwritten during the build. You should treat \
//           component.jsx as your entry point. As long as you provide the correct\
//           exports from there everything should work."
//         }]
//       }
//     } else {
//       await applyFileOps(inputVars.file_ops);
//       const directoryStructure = makeAsciiDirectoryStructure(
//         inputVars.apptile_context.plugin_root, 
//         file_paths_copy
//       );
//       return {
//         content: [{
//           type: "text",
//           text: `file_ops completed successfully! These files are now written:
// ${directoryStructure}.`
//         }]
//       }
//     }
//   }
// );

// server.tool(
//   "lookup_available_icons",
//   "Search the list of available icons in the platform. The value returned will contain the values for iconType and name.",
//   {
//     "search_string": z.string().describe("Search for an icon by the name of the icon. This performs a fuzzy search. "),
//     apptile_context: z.object({
//       plugin_root: z.string()
//     }).nullable().describe("This should always be passed as null by the LLM. It will be set to the correct path by the tool.")
//   },
//   async (inputVars) => {
//     const icons = searchIcons(inputVars.search_string);
    
//     return {
//       content: [{
//         type: "text",
//         text: JSON.stringify(icons)
//       }]
//     };
//   }
// );

// server.tool(
//   "http_request",
//   "Make an HTTP request to inspect API responses. This tool is useful when integrating apis if enough information doesn't exist in the context to know what the response format would be. This tool uses axios to run the calls.",
//   {
//     url: z.string().url().describe("The full URL to make a request to"),
//     method: z.enum(["GET", "POST", "PUT", "DELETE"]).default("GET"),
//     headers: z.record(z.string()).optional(),
//     body: z.union([z.string(), z.record(z.any())]).optional()
//   },
//   async ({ url, method, headers, body }) => {
//     // Optional domain whitelist
//     // const allowedDomains = ["api.example.com", "jsonplaceholder.typicode.com"];
//     // const domain = new URL(url).hostname;
//     // if (!allowedDomains.includes(domain)) {
//     //   throw new Error(`Domain not allowed: ${domain}`);
//     // }

//     try {
//       const response = await axios.request({
//         url,
//         method,
//         headers,
//         data: body,
//       });

//       return {
//         content: [
//           {
//             type: "text",
//             text: `Status: ${response.status}\n\nResponse:\n${JSON.stringify(response.data, null, 2)}`,
//           },
//         ],
//       };
//     } catch (error: any) {
//       return {
//         content: [
//           {
//             type: "text",
//             text: `Request failed:\n${error.message}\n\n${
//               error.response
//                 ? `Status: ${error.response.status}\n${JSON.stringify(error.response.data, null, 2)}`
//                 : ""
//             }`,
//           },
//         ],
//       };
//     }
//   }
// )

// async function main() {
//   const transport = new StdioServerTransport();
//   await server.connect(transport);
//   console.error("Apptile Graphql MCP Server running on stdio");
// }

// main().catch((error) => {
//   console.error("Fatal error in main():", error);
//   process.exit(1);
// });
