// Copyright (c) 2022 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package registry

const (
	JsonGoTemplateType = "json-go-template"

	IstioMcpAutoGeneratedPrefix        = "istio-autogenerated-mcp"
	IstioMcpAutoGeneratedVsName        = IstioMcpAutoGeneratedPrefix + "-vs"
	IstioMcpAutoGeneratedSeName        = IstioMcpAutoGeneratedPrefix + "-se"
	IstioMcpAutoGeneratedDrName        = IstioMcpAutoGeneratedPrefix + "-dr"
	IstioMcpAutoGeneratedHttpRouteName = IstioMcpAutoGeneratedPrefix + "-httproute"
	IstioMcpAutoGeneratedMcpServerName = IstioMcpAutoGeneratedPrefix + "-mcpserver"

	StdioProtocol         = "stdio"
	HttpProtocol          = "http"
	HttpsProtocol         = "https"
	DubboProtocol         = "dubbo"
	McpSSEProtocol        = "mcp-sse"
	McpStreamableProtocol = "mcp-streamable"
)

type McpToolArgsType string

// WasmPluginConfig Struct for mcp tool wasm plugin marshal
type WasmPluginConfig struct {
	Rules []*McpServerRule `json:"_rules_,omitempty"`
}

type McpServerRule struct {
	MatchRoute []string      `json:"_match_route_,omitempty"`
	Server     *ServerConfig `json:"server,omitempty"`
	Tools      []*McpTool    `json:"tools,omitempty"`
	AllowTools []string      `json:"allowTools,omitempty"`
}

type ServerConfig struct {
	Name            string                 `json:"name,omitempty"`
	Config          map[string]interface{} `json:"config,omitempty"`
	SecuritySchemes []*SecuritySchemes     `json:"securitySchemes,omitempty"`
}

type McpTool struct {
	Name                  string            `json:"name,omitempty"`
	Description           string            `json:"description,omitempty"`
	Args                  []*ToolArgs       `json:"args,omitempty"`
	RequestTemplate       *RequestTemplate  `json:"requestTemplate"`
	ResponseTemplate      *ResponseTemplate `json:"responseTemplate"`
	ErrorResponseTemplate string            `json:"errorResponseTemplate,omitempty"`
	Security              *ToolSecurity     `json:"security"`
}

type ToolSecurity struct {
	Id          string `json:"id,omitempty"`
	PassThrough bool   `json:"passthrough,omitempty"`
	Credential  string `json:"credential"`
}

type ToolArgs struct {
	Name        string        `json:"name,omitempty"`
	Description string        `json:"description,omitempty"`
	Type        string        `json:"type,omitempty"`
	Required    bool          `json:"required,omitempty"`
	Default     interface{}   `json:"default,omitempty"`
	Enum        []interface{} `json:"enum,omitempty"`
	Items       interface{}   `json:"items,omitempty"`
	Properties  interface{}   `json:"properties,omitempty"`
	Position    string        `json:"position,omitempty"`
}

type RequestTemplate struct {
	URL            string                    `json:"url"`
	Method         string                    `json:"method"`
	Headers        []*RequestTemplateHeaders `json:"headers,omitempty"`
	Body           string                    `json:"body,omitempty"`
	ArgsToJsonBody bool                      `json:"argsToJsonBody,omitempty"`
	ArgsToUrlParam bool                      `json:"argsToUrlParam,omitempty"`
	ArgsToFormBody bool                      `json:"argsToFormBody,omitempty"`
	Security       *ToolSecurity             `json:"security,omitempty"`
}

type RequestTemplateHeaders struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

type ResponseTemplate struct {
	Body        string `json:"body,omitempty"`
	PrependBody string `json:"prependBody,omitempty"`
	AppendBody  string `json:"appendBody,omitempty"`
}

// McpServer Struct for mcp server json unmarshal
type McpServer struct {
	Protocol               string                    `json:"protocol,omitempty"`
	Name                   string                    `json:"name,omitempty"`
	Description            string                    `json:"description,omitempty"`
	Version                string                    `json:"version,omitempty"`
	Enabled                bool                      `json:"enabled,omitempty"`
	RemoteServerConfig     *RemoteServerConfig       `json:"remoteServerConfig,omitempty"`
	Credentials            map[string]*CredentialRef `json:"credentials,omitempty"`
	ToolsDescriptionRef    string                    `json:"toolsDescriptionRef,omitempty"`
	PromptDescriptionRef   string                    `json:"promptDescriptionRef,omitempty"`
	ResourceDescriptionRef string                    `json:"resourceDescriptionRef,omitempty"`
}

type RemoteServerConfig struct {
	ServiceRef      *ServiceRef `json:"serviceRef,omitempty"`
	ExportPath      string      `json:"exportPath,omitempty"`
	BackendProtocol string      `json:"backendProtocol,omitempty"`
}

type CredentialRef struct {
	Ref string `json:"ref,omitempty"`
}

type ServiceRef struct {
	NamespaceId string `json:"namespaceId,omitempty"`
	GroupName   string `json:"groupName,omitempty"`
	ServiceName string `json:"serviceName,omitempty"`
}

// McpToolConfig Struct for mcp tool json unmarshal
type McpToolConfig struct {
	Tools           []*ToolDescription    `json:"tools,omitempty"`
	ToolsMeta       map[string]*ToolsMeta `json:"toolsMeta,omitempty"`
	SecuritySchemes []*SecuritySchemes    `json:"securitySchemes,omitempty"`
}

type SecuritySchemes struct {
	Id                string `json:"id,omitempty"`
	Type              string `json:"type,omitempty"`
	Scheme            string `json:"scheme,omitempty"`
	In                string `json:"in,omitempty"`
	Name              string `json:"name,omitempty"`
	DefaultCredential string `json:"defaultCredential,omitempty"`
}

type ToolDescription struct {
	Name        string      `json:"name,omitempty"`
	Description string      `json:"description,omitempty"`
	InputSchema InputSchema `json:"inputSchema"`
}

type InputSchema struct {
	Type       string                 `json:"type,omitempty"`
	Properties map[string]interface{} `json:"properties,omitempty"`
	Required   []string               `json:"required,omitempty"`
}

type ToolsMeta struct {
	InvokeContext map[string]string      `json:"invokeContext,omitempty"`
	Enabled       bool                   `json:"enabled,omitempty"`
	Templates     map[string]interface{} `json:"templates,omitempty"`
}

type JsonGoTemplate struct {
	RequestTemplate       RequestTemplate   `json:"requestTemplate,omitempty"`
	ResponseTemplate      ResponseTemplate  `json:"responseTemplate,omitempty"`
	ArgsPosition          map[string]string `json:"argsPosition,omitempty"`
	ErrorResponseTemplate string            `json:"errorResponseTemplate,omitempty"`
	Security              *ToolSecurity     `json:"security,omitempty"`
}
