// Copyright (c) 2024 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 main

import (
	"encoding/json"
	"testing"

	"github.com/higress-group/proxy-wasm-go-sdk/proxywasm/types"
	"github.com/higress-group/wasm-go/pkg/test"
	"github.com/santhosh-tekuri/jsonschema"
	"github.com/stretchr/testify/require"
)

// 测试配置：基础配置
var basicConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"serviceName":              "ai-service",
		"serviceDomain":            "api.openai.com",
		"servicePort":              443,
		"servicePath":              "/v1/chat/completions",
		"apiKey":                   "sk-test123",
		"serviceTimeout":           30000,
		"maxRetry":                 3,
		"contentPath":              "choices.0.message.content",
		"enableContentDisposition": true,
		// 添加一个简单的JSON Schema，避免编译失败
		"jsonSchema": map[string]interface{}{
			"type": "object",
			"properties": map[string]interface{}{
				"content": map[string]interface{}{
					"type": "string",
				},
			},
		},
	})
	return data
}()

// 测试配置：使用serviceUrl的配置
var serviceUrlConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"serviceName":              "ai-service",
		"serviceUrl":               "https://api.openai.com/v1/chat/completions",
		"apiKey":                   "sk-test456",
		"serviceTimeout":           50000,
		"maxRetry":                 5,
		"contentPath":              "choices.0.message.content",
		"enableContentDisposition": false,
		// 添加一个简单的JSON Schema，避免编译失败
		"jsonSchema": map[string]interface{}{
			"type": "object",
			"properties": map[string]interface{}{
				"content": map[string]interface{}{
					"type": "string",
				},
			},
		},
	})
	return data
}()

// 测试配置：包含JSON Schema的配置
var jsonSchemaConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"serviceName":   "ai-service",
		"serviceDomain": "api.openai.com",
		"servicePort":   443,
		"apiKey":        "sk-test789",
		"jsonSchema": map[string]interface{}{
			"type": "object",
			"properties": map[string]interface{}{
				"name": map[string]interface{}{
					"type": "string",
				},
				"age": map[string]interface{}{
					"type": "integer",
				},
			},
			"required": []string{"name"},
		},
		"enableSwagger": true,
		"enableOas3":    false,
	})
	return data
}()

// 测试配置：启用OAS3的配置
var oas3Config = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"serviceName":   "ai-service",
		"serviceDomain": "api.openai.com",
		"servicePort":   443,
		"apiKey":        "sk-test101",
		"jsonSchema": map[string]interface{}{
			"type": "object",
			"properties": map[string]interface{}{
				"title": map[string]interface{}{
					"type": "string",
				},
				"content": map[string]interface{}{
					"type": "string",
				},
			},
		},
		"enableSwagger": false,
		"enableOas3":    true,
	})
	return data
}()

// 测试配置：无效的JSON Schema配置
var invalidJsonSchemaConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"serviceName":   "ai-service",
		"serviceDomain": "api.openai.com",
		"servicePort":   443,
		"apiKey":        "sk-test303",
		"jsonSchema":    "invalid-schema",
	})
	return data
}()

// 测试配置：缺少必需字段的配置
var missingRequiredConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"apiKey":         "sk-test404",
		"serviceTimeout": 30000,
	})
	return data
}()

func TestParseConfig(t *testing.T) {
	test.RunGoTest(t, func(t *testing.T) {
		// 测试基础配置解析
		t.Run("basic config", func(t *testing.T) {
			host, status := test.NewTestHost(basicConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)
			config, err := host.GetMatchConfig()
			require.NoError(t, err)
			require.NotNil(t, config)

			pluginConfig := config.(*PluginConfig)
			require.Equal(t, "ai-service", pluginConfig.serviceName)
			require.Equal(t, "api.openai.com", pluginConfig.serviceDomain)
			require.Equal(t, 443, pluginConfig.servicePort)
			require.Equal(t, "/v1/chat/completions", pluginConfig.servicePath)
			require.Equal(t, "sk-test123", pluginConfig.apiKey)
			require.Equal(t, 30000, pluginConfig.serviceTimeout)
			require.Equal(t, 3, pluginConfig.maxRetry)
			require.Equal(t, "choices.0.message.content", pluginConfig.contentPath)
			require.True(t, pluginConfig.enableContentDisposition)
			require.NotNil(t, pluginConfig.jsonSchema)
			require.Equal(t, jsonschema.Draft7, pluginConfig.draft)
			require.True(t, pluginConfig.enableJsonSchemaValidation)
		})

		// 测试使用serviceUrl的配置解析
		t.Run("serviceUrl config", func(t *testing.T) {
			host, status := test.NewTestHost(serviceUrlConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)
			config, err := host.GetMatchConfig()
			require.NoError(t, err)
			require.NotNil(t, config)

			pluginConfig := config.(*PluginConfig)
			require.Equal(t, "ai-service", pluginConfig.serviceName)
			require.Equal(t, "api.openai.com", pluginConfig.serviceDomain)
			require.Equal(t, 443, pluginConfig.servicePort)
			require.Equal(t, "/v1/chat/completions", pluginConfig.servicePath)
			require.Equal(t, "sk-test456", pluginConfig.apiKey)
			require.Equal(t, 50000, pluginConfig.serviceTimeout)
			require.Equal(t, 5, pluginConfig.maxRetry)
			require.False(t, pluginConfig.enableContentDisposition)
		})

		// 测试包含JSON Schema的配置解析
		t.Run("jsonSchema config", func(t *testing.T) {
			host, status := test.NewTestHost(jsonSchemaConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)
			config, err := host.GetMatchConfig()
			require.NoError(t, err)
			require.NotNil(t, config)

			pluginConfig := config.(*PluginConfig)
			require.NotNil(t, pluginConfig.jsonSchema)
			require.Equal(t, jsonschema.Draft4, pluginConfig.draft)
			require.True(t, pluginConfig.enableJsonSchemaValidation)
			require.NotNil(t, pluginConfig.compile)
		})

		// 测试启用OAS3的配置解析
		t.Run("oas3 config", func(t *testing.T) {
			host, status := test.NewTestHost(oas3Config)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)
			config, err := host.GetMatchConfig()
			require.NoError(t, err)
			require.NotNil(t, config)

			pluginConfig := config.(*PluginConfig)
			require.Equal(t, jsonschema.Draft7, pluginConfig.draft)
			require.True(t, pluginConfig.enableJsonSchemaValidation)
		})

		// 测试无效的JSON Schema配置
		t.Run("invalid jsonSchema config", func(t *testing.T) {
			host, status := test.NewTestHost(invalidJsonSchemaConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)
			config, err := host.GetMatchConfig()
			require.NoError(t, err)
			require.NotNil(t, config)

			pluginConfig := config.(*PluginConfig)
			// 根据插件的实际行为，无效的JSON Schema会导致编译失败
			require.Equal(t, uint32(JSON_SCHEMA_COMPILE_FAILED_CODE), pluginConfig.rejectStruct.RejectCode)
		})

		// 测试缺少必需字段的配置
		t.Run("missing required config", func(t *testing.T) {
			host, status := test.NewTestHost(missingRequiredConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)
			config, _ := host.GetMatchConfig()
			require.NotNil(t, config)

			pluginConfig := config.(*PluginConfig)
			// 根据插件的实际行为，缺少serviceDomain会导致JSON Schema编译失败
			require.Equal(t, uint32(JSON_SCHEMA_COMPILE_FAILED_CODE), pluginConfig.rejectStruct.RejectCode)
			require.Contains(t, pluginConfig.rejectStruct.RejectMsg, "Json Schema compile failed")
		})
	})
}

func TestOnHttpRequestHeaders(t *testing.T) {
	test.RunTest(t, func(t *testing.T) {
		// 测试正常请求头处理
		t.Run("normal request headers", func(t *testing.T) {
			host, status := test.NewTestHost(basicConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			action := host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{"Authorization", "Bearer sk-user123"},
				{"Content-Type", "application/json"},
				{"Content-Length", "100"},
			})

			// 应该返回ActionContinue
			require.Equal(t, types.ActionContinue, action)
		})

		// 测试来自插件的请求头处理
		t.Run("request from this plugin", func(t *testing.T) {
			host, status := test.NewTestHost(basicConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置来自插件的请求头
			action := host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{EXTEND_HEADER_KEY, "true"},
				{"Content-Type", "application/json"},
			})

			// 应该返回ActionContinue
			require.Equal(t, types.ActionContinue, action)
		})

		// 测试没有Authorization头的请求
		t.Run("no authorization header", func(t *testing.T) {
			host, status := test.NewTestHost(basicConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置没有Authorization的请求头
			action := host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{"Content-Type", "application/json"},
				{"Content-Length", "100"},
			})

			// 应该返回ActionContinue
			require.Equal(t, types.ActionContinue, action)
		})

		// 测试配置错误的请求头处理
		t.Run("config error", func(t *testing.T) {
			host, status := test.NewTestHost(missingRequiredConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			action := host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{"Content-Type", "application/json"},
			})

			// 应该返回ActionPause
			require.Equal(t, types.ActionPause, action)
		})
	})
}

func TestOnHttpRequestBody(t *testing.T) {
	test.RunTest(t, func(t *testing.T) {
		// 测试来自插件的请求（应该直接继续）
		t.Run("request from this plugin", func(t *testing.T) {
			host, status := test.NewTestHost(basicConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头，包含EXTEND_HEADER_KEY来标记请求来自插件
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{"Content-Type", "application/json"},
				{EXTEND_HEADER_KEY, "true"},
			})

			// 设置请求体
			body := `{
				"model": "gpt-3.5-turbo",
				"messages": [
					{"role": "user", "content": "Hello"}
				]
			}`

			action := host.CallOnHttpRequestBody([]byte(body))
			// 应该返回ActionContinue，因为请求来自插件
			require.Equal(t, types.ActionContinue, action)
		})

		// 测试配置错误的请求体处理
		t.Run("config error", func(t *testing.T) {
			host, status := test.NewTestHost(missingRequiredConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{"Content-Type", "application/json"},
			})

			// 设置请求体
			body := `{
				"model": "gpt-3.5-turbo",
				"messages": [
					{"role": "user", "content": "Hello"}
				]
			}`

			action := host.CallOnHttpRequestBody([]byte(body))
			// 应该返回ActionContinue，因为配置有错误
			require.Equal(t, types.ActionContinue, action)
		})

		// 测试正常请求体处理 - 成功响应
		t.Run("normal request with successful response", func(t *testing.T) {
			host, status := test.NewTestHost(basicConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{"Content-Type", "application/json"},
			})

			// 设置请求体
			body := `{
				"model": "gpt-3.5-turbo",
				"messages": [
					{"role": "user", "content": "What is AI?"}
				]
			}`

			action := host.CallOnHttpRequestBody([]byte(body))
			// 应该返回ActionPause，等待外部服务响应
			require.Equal(t, types.ActionPause, action)

			// 模拟外部服务返回成功响应
			host.CallOnHttpCall([][2]string{
				{":status", "200"},
				{"content-type", "application/json"},
			}, []byte(`{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"definition\": \"AI is artificial intelligence\", \"examples\": [\"machine learning\", \"natural language processing\"]}"
						}
					}
				]
			}`))

			response := host.GetLocalResponse()
			require.NotNil(t, response)
			require.Contains(t, string(response.Data), "definition")
			require.Contains(t, string(response.Data), "examples")

			// 完成HTTP请求
			host.CompleteHttp()
		})

		// 测试正常请求体处理 - 需要重试的响应
		t.Run("normal request with retry response", func(t *testing.T) {
			host, status := test.NewTestHost(basicConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{"Content-Type", "application/json"},
			})

			// 设置请求体
			body := `{
				"model": "gpt-3.5-turbo",
				"messages": [
					{"role": "user", "content": "What is AI?"}
				]
			}`

			action := host.CallOnHttpRequestBody([]byte(body))
			// 应该返回ActionPause，等待外部服务响应
			require.Equal(t, types.ActionPause, action)

			// 模拟外部服务返回需要重试的响应（content字段不是有效JSON）
			host.CallOnHttpCall([][2]string{
				{":status", "200"},
				{"content-type", "application/json"},
			}, []byte(`{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "AI is artificial intelligence. It includes machine learning and natural language processing."
						}
					}
				]
			}`))

			// 由于content不是有效JSON，插件会进行重试
			// 模拟重试请求的响应
			host.CallOnHttpCall([][2]string{
				{":status", "200"},
				{"content-type", "application/json"},
			}, []byte(`{
				"id": "chatcmpl-456",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"definition\": \"AI is artificial intelligence\", \"examples\": [\"machine learning\", \"natural language processing\"]}"
						}
					}
				]
			}`))

			// 验证最终响应体是提取的JSON内容
			response := host.GetLocalResponse()
			require.NotNil(t, response)
			require.Contains(t, string(response.Data), "definition")
			require.Contains(t, string(response.Data), "examples")

			// 完成HTTP请求
			host.CompleteHttp()
		})

		// 测试外部服务返回无效响应体
		t.Run("external service returns invalid response body", func(t *testing.T) {
			host, status := test.NewTestHost(basicConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{"Content-Type", "application/json"},
			})

			// 设置请求体
			body := `{
				"model": "gpt-3.5-turbo",
				"messages": [
					{"role": "user", "content": "What is AI?"}
				]
			}`

			action := host.CallOnHttpRequestBody([]byte(body))
			// 应该返回ActionPause，等待外部服务响应
			require.Equal(t, types.ActionPause, action)

			// 模拟外部服务返回无效的响应体
			host.CallOnHttpCall([][2]string{
				{":status", "200"},
				{"content-type", "application/json"},
			}, []byte(`invalid json response`))

			// 验证响应体包含错误信息
			response := host.GetLocalResponse()
			require.NotNil(t, response)
			require.Contains(t, string(response.Data), "invalid json response")

			// 完成HTTP请求
			host.CompleteHttp()
		})

		// 测试外部服务返回缺少content字段的响应
		t.Run("external service returns response without content field", func(t *testing.T) {
			host, status := test.NewTestHost(basicConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{"Content-Type", "application/json"},
			})

			// 设置请求体
			body := `{
				"model": "gpt-3.5-turbo",
				"messages": [
					{"role": "user", "content": "What is AI?"}
				]
			}`

			action := host.CallOnHttpRequestBody([]byte(body))
			// 应该返回ActionPause，等待外部服务响应
			require.Equal(t, types.ActionPause, action)

			// 模拟外部服务返回缺少content字段的响应
			host.CallOnHttpCall([][2]string{
				{":status", "200"},
				{"content-type", "application/json"},
			}, []byte(`{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant"
						}
					}
				]
			}`))

			// 验证响应体包含错误信息
			response := host.GetLocalResponse()
			require.NotNil(t, response)
			require.Contains(t, string(response.Data), "response body does not contain the content")

			// 完成HTTP请求
			host.CompleteHttp()
		})

		// 测试使用自定义servicePath的请求
		t.Run("request with custom service path", func(t *testing.T) {
			host, status := test.NewTestHost(serviceUrlConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/custom/chat"},
				{":method", "POST"},
				{"Content-Type", "application/json"},
			})

			// 设置请求体
			body := `{
				"model": "gpt-3.5-turbo",
				"messages": [
					{"role": "user", "content": "What is AI?"}
				]
			}`

			action := host.CallOnHttpRequestBody([]byte(body))
			// 应该返回ActionPause，等待外部服务响应
			require.Equal(t, types.ActionPause, action)

			// 模拟外部服务返回成功响应
			host.CallOnHttpCall([][2]string{
				{":status", "200"},
				{"content-type", "application/json"},
			}, []byte(`{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"answer\": \"AI is artificial intelligence\"}"
						}
					}
				]
			}`))

			// 验证响应体是提取的JSON内容
			response := host.GetLocalResponse()
			require.NotNil(t, response)
			require.Contains(t, string(response.Data), "answer")

			// 完成HTTP请求
			host.CompleteHttp()
		})

		// 测试达到最大重试次数的情况
		t.Run("max retry count exceeded", func(t *testing.T) {
			host, status := test.NewTestHost(basicConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/v1/chat/completions"},
				{":method", "POST"},
				{"Content-Type", "application/json"},
			})

			// 设置请求体
			body := `{
				"model": "gpt-3.5-turbo",
				"messages": [
					{"role": "user", "content": "What is AI?"}
				]
			}`

			action := host.CallOnHttpRequestBody([]byte(body))
			// 应该返回ActionPause，等待外部服务响应
			require.Equal(t, types.ActionPause, action)

			// 模拟多次重试，每次都返回无效的content
			for i := 0; i < 4; i++ { // 超过最大重试次数3次
				host.CallOnHttpCall([][2]string{
					{":status", "200"},
					{"content-type", "application/json"},
				}, []byte(`{
					"id": "chatcmpl-123",
					"choices": [
						{
							"index": 0,
							"message": {
								"role": "assistant",
								"content": "AI is artificial intelligence"
							}
						}
					]
				}`))
			}

			// 验证最终响应体包含重试次数超限的错误信息
			response := host.GetLocalResponse()
			require.NotNil(t, response)
			require.Contains(t, string(response.Data), "retry count exceeds max retry count")

			// 完成HTTP请求
			host.CompleteHttp()
		})
	})
}

func TestRejectStruct(t *testing.T) {
	// 测试RejectStruct的GetBytes方法
	t.Run("GetBytes", func(t *testing.T) {
		reject := RejectStruct{
			RejectCode: 1001,
			RejectMsg:  "Test error message",
		}

		bytes := reject.GetBytes()
		require.NotNil(t, bytes)

		// 验证JSON格式
		var result RejectStruct
		err := json.Unmarshal(bytes, &result)
		require.NoError(t, err)
		require.Equal(t, uint32(1001), result.RejectCode)
		require.Equal(t, "Test error message", result.RejectMsg)
	})

	// 测试RejectStruct的GetShortMsg方法
	t.Run("GetShortMsg", func(t *testing.T) {
		reject := RejectStruct{
			RejectCode: 1001,
			RejectMsg:  "Json Schema is not valid: invalid format",
		}

		shortMsg := reject.GetShortMsg()
		require.Equal(t, "ai-json-resp.Json Schema is not valid", shortMsg)
	})

	// 测试RejectStruct的GetShortMsg方法 - 没有冒号的情况
	t.Run("GetShortMsg no colon", func(t *testing.T) {
		reject := RejectStruct{
			RejectCode: 1001,
			RejectMsg:  "Simple error message",
		}

		shortMsg := reject.GetShortMsg()
		require.Equal(t, "ai-json-resp.Simple error message", shortMsg)
	})
}

func TestValidateBody(t *testing.T) {
	// 创建测试配置
	config := &PluginConfig{
		contentPath:                "choices.0.message.content",
		jsonSchema:                 nil,   // 明确设置为nil，禁用JSON Schema验证
		enableJsonSchemaValidation: false, // 禁用JSON Schema验证
	}

	// 测试有效的响应体
	t.Run("valid response body", func(t *testing.T) {
		validBody := []byte(`{
			"id": "chatcmpl-123",
			"choices": [
				{
					"index": 0,
					"message": {
						"role": "assistant",
						"content": "Hello, how can I help you?"
					}
				}
			]
		}`)
		err := config.ValidateBody(validBody)
		require.NoError(t, err)
	})

	// 测试无效的JSON响应体
	t.Run("invalid JSON response body", func(t *testing.T) {
		invalidBody := []byte(`invalid json content`)

		err := config.ValidateBody(invalidBody)
		require.Error(t, err)
		require.Equal(t, uint32(SERVICE_UNAVAILABLE_CODE), config.rejectStruct.RejectCode)
		require.Contains(t, config.rejectStruct.RejectMsg, "service unavailable")
	})

	// 测试缺少content字段的响应体
	t.Run("missing content field", func(t *testing.T) {
		missingContentBody := []byte(`{
			"id": "chatcmpl-123",
			"choices": [
				{
					"index": 0,
					"message": {
						"role": "assistant"
					}
				}
			]
		}`)

		err := config.ValidateBody(missingContentBody)
		require.Error(t, err)
		require.Equal(t, uint32(SERVICE_UNAVAILABLE_CODE), config.rejectStruct.RejectCode)
		require.Contains(t, config.rejectStruct.RejectMsg, "response body does not contain the content")
	})

	// 测试空的响应体
	t.Run("empty response body", func(t *testing.T) {
		emptyBody := []byte{}

		err := config.ValidateBody(emptyBody)
		require.Error(t, err)
		require.Equal(t, uint32(SERVICE_UNAVAILABLE_CODE), config.rejectStruct.RejectCode)
	})
}

func TestExtractJson(t *testing.T) {
	// 创建测试配置
	config := &PluginConfig{
		jsonSchema:                 nil,   // 明确设置为nil，禁用JSON Schema验证
		enableJsonSchemaValidation: false, // 禁用JSON Schema验证
	}

	// 测试提取有效的JSON
	t.Run("extract valid JSON", func(t *testing.T) {
		content := `Here is the response: {"name": "John", "age": 30} and some other text`

		jsonStr, err := config.ExtractJson(content)
		require.NoError(t, err)
		require.Equal(t, `{"name": "John", "age": 30}`, jsonStr)
	})

	// 测试提取嵌套JSON
	t.Run("extract nested JSON", func(t *testing.T) {
		content := `Response: {"user": {"name": "John", "profile": {"age": 30, "city": "NYC"}}}`

		jsonStr, err := config.ExtractJson(content)
		require.NoError(t, err)
		require.Equal(t, `{"user": {"name": "John", "profile": {"age": 30, "city": "NYC"}}}`, jsonStr)
	})

	// 测试没有JSON的内容
	t.Run("no JSON in content", func(t *testing.T) {
		content := `This is just plain text without any JSON content`

		_, err := config.ExtractJson(content)
		require.Error(t, err)
		require.Contains(t, err.Error(), "cannot find json in the response body")
	})

	// 测试只有开始括号的内容
	t.Run("only opening brace", func(t *testing.T) {
		content := `Here is the start: { but no closing brace`

		_, err := config.ExtractJson(content)
		require.Error(t, err)
		require.Contains(t, err.Error(), "cannot find json in the response body")
	})

	// 测试只有结束括号的内容
	t.Run("only closing brace", func(t *testing.T) {
		content := `Here is the end: } but no opening brace`

		_, err := config.ExtractJson(content)
		require.Error(t, err)
		require.Contains(t, err.Error(), "cannot find json in the response body")
	})

	// 测试无效的JSON格式
	t.Run("invalid JSON format", func(t *testing.T) {
		content := `Here is invalid JSON: {"name": "John", "age": 30,}`

		_, err := config.ExtractJson(content)
		require.Error(t, err)
		// ExtractJson会提取到{"name": "John", "age": 30,}，但json.Unmarshal会失败
		// 因为JSON格式无效（末尾有多余的逗号）
		require.Contains(t, err.Error(), "invalid character '}' looking for beginning of object key string")
	})

	// 测试多个JSON对象（应该提取第一个完整的）
	t.Run("multiple JSON objects", func(t *testing.T) {
		content := `First: {"name": "John"} Second: {"age": 30}`

		_, err := config.ExtractJson(content)
		require.Error(t, err)
		// ExtractJson会提取到{"name": "John"} Second: {"age": 30}
		// 这不是有效的JSON，因为"Second: {"age": 30}"不是有效的JSON语法
		require.Contains(t, err.Error(), "invalid character 'S' after top-level value")
	})
}
