content: /*
   * Copyright 2024-2024 the original author or authors.
   */
  
  package com.alibaba.langengine.modelcontextprotocol.spec;
  
  import lombok.Data;
  
  import com.fasterxml.jackson.core.type.TypeReference;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.io.IOException;
  import java.util.HashMap;
  import java.util.Map;
  
  /**
   * Based on the <a href="http://www.jsonrpc.org/specification">JSON-RPC 2.0
   * specification</a> and the <a href=
   * "https://github.com/modelcontextprotocol/specification/blob/main/schema/schema.ts">Model
   * Context Protocol Schema</a>.
   *
   * JDK 1.8 compatible version.
   *
   * @author Christian Tzolov
   */
  public final class McpSchema {
  
      private static final Logger logger = LoggerFactory.getLogger(McpSchema.class);
  
      private McpSchema() {
      }
  
      public static final String LATEST_PROTOCOL_VERSION = "2024-11-05";
  
      public static final String JSONRPC_VERSION = "2.0";
  
      // ---------------------------
      // Method Names
      // ---------------------------
  
      // Lifecycle Methods
      public static final String METHOD_INITIALIZE = "initialize";
  
      public static final String METHOD_NOTIFICATION_INITIALIZED = "notifications/initialized";
  
      public static final String METHOD_PING = "ping";
  
      // Tool Methods
      public static final String METHOD_TOOLS_LIST = "tools/list";
  
      public static final String METHOD_TOOLS_CALL = "tools/call";
  
      public static final String METHOD_NOTIFICATION_TOOLS_LIST_CHANGED = "notifications/tools/list_changed";
  
      // Resources Methods
      public static final String METHOD_RESOURCES_LIST = "resources/list";
  
      public static final String METHOD_RESOURCES_READ = "resources/read";
  
      public static final String METHOD_NOTIFICATION_RESOURCES_LIST_CHANGED = "notifications/resources/list_changed";
  
      public static final String METHOD_RESOURCES_TEMPLATES_LIST = "resources/templates/list";
  
      public static final String METHOD_RESOURCES_SUBSCRIBE = "resources/subscribe";
  
      public static final String METHOD_RESOURCES_UNSUBSCRIBE = "resources/unsubscribe";
  
      // Prompt Methods
      public static final String METHOD_PROMPT_LIST = "prompts/list";
  
      public static final String METHOD_PROMPT_GET = "prompts/get";
  
      public static final String METHOD_NOTIFICATION_PROMPTS_LIST_CHANGED = "notifications/prompts/list_changed";
  
      // Logging Methods
      public static final String METHOD_LOGGING_SET_LEVEL = "logging/setLevel";
  
      public static final String METHOD_NOTIFICATION_MESSAGE = "notifications/message";
  
      // Roots Methods
      public static final String METHOD_ROOTS_LIST = "roots/list";
  
      public static final String METHOD_NOTIFICATION_ROOTS_LIST_CHANGED = "notifications/roots/list_changed";
  
      // Sampling Methods
      public static final String METHOD_SAMPLING_CREATE_MESSAGE = "sampling/createMessage";
  
      private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
  
      // ---------------------------
      // JSON-RPC Error Codes
      // ---------------------------
  
      /**
       * Request interface replacing sealed interface in JDK 1.8
       */
      public interface Request {
      }
  
      private static final TypeReference<HashMap<String, Object>> MAP_TYPE_REF = new TypeReference<HashMap<String, Object>>() {
      };
  
      /**
       * Deserializes a JSON string into a JSONRPCMessage object.
       * @param objectMapper The ObjectMapper instance to use for deserialization
       * @param jsonText The JSON string to deserialize
       * @return A JSONRPCMessage instance using either the {@link JSONRPCRequest},
       * {@link JSONRPCNotification}, or {@link JSONRPCResponse} classes.
       * @throws IOException If there's an error during deserialization
       * @throws IllegalArgumentException If the JSON structure doesn't match any known
       * message type
       */
      public static JSONRPCMessage deserializeJsonRpcMessage(ObjectMapper objectMapper, String jsonText)
              throws IOException {
  
          logger.debug("Received JSON message: {}", jsonText);
  
          Map<String, Object> map = objectMapper.readValue(jsonText, MAP_TYPE_REF);
  
          // Determine message type based on specific JSON structure
          if (map.containsKey("method") && map.containsKey("id")) {
              return objectMapper.convertValue(map, JSONRPCRequest.class);
          }
          else if (map.containsKey("method") && !map.containsKey("id")) {
              return objectMapper.convertValue(map, JSONRPCNotification.class);
          }
          else if (map.containsKey("result") || map.containsKey("error")) {
              return objectMapper.convertValue(map, JSONRPCResponse.class);
          }
  
          throw new IllegalArgumentException("Cannot deserialize JSONRPCMessage: " + jsonText);
      }
  
      // Additional classes will be added in separate files to keep the implementation modular
  
  
  
  
  }
  