package main

import (
	"fmt"
	"strings"

	"github.com/buger/jsonparser"
)

func main() {
	fmt.Println("=== 从不完整 JSON 中提取字段值的示例 ===")
	fmt.Println()

	// 测试案例 1: 不完整的字符串值
	fmt.Println("1. 提取不完整的字符串值:")
	incompleteJSON1 := `{"name": "Alice", "info": "hello world this is incomplete`
	if value, found := ExtractIncompleteValue(incompleteJSON1, "info"); found {
		fmt.Printf("   提取到的值: %s\n", value)
	} else {
		fmt.Println("   未找到该字段")
	}

	// 测试案例 2: 完整的字符串后面还有不完整的字段
	fmt.Println("\n2. 提取完整字段和不完整字段:")
	incompleteJSON2 := `{"status": "ok", "data": "complete data", "partial": "incomp`
	if value, found := ExtractIncompleteValue(incompleteJSON2, "status"); found {
		fmt.Printf("   status: %s (完整)\n", value)
	}
	if value, found := ExtractIncompleteValue(incompleteJSON2, "data"); found {
		fmt.Printf("   data: %s (完整)\n", value)
	}
	if value, found := ExtractIncompleteValue(incompleteJSON2, "partial"); found {
		fmt.Printf("   partial: %s (不完整)\n", value)
	}

	// 测试案例 3: 处理转义字符
	fmt.Println("\n3. 处理带转义的不完整字符串:")
	incompleteJSON3 := `{"text": "hello \"world\" this is \n incomplete`
	if value, found := ExtractIncompleteValue(incompleteJSON3, "text"); found {
		fmt.Printf("   提取到的值: %s\n", value)
	}

	// 测试案例 4: 数字和布尔值（不完整）
	fmt.Println("\n4. 提取不完整的数字值:")
	incompleteJSON4 := `{"count": 12345, "price": 99.`
	if value, found := ExtractIncompleteValue(incompleteJSON4, "count"); found {
		fmt.Printf("   count: %s (完整)\n", value)
	}
	if value, found := ExtractIncompleteValue(incompleteJSON4, "price"); found {
		fmt.Printf("   price: %s (不完整)\n", value)
	}

	// 测试案例 5: 嵌套对象（部分不完整）
	fmt.Println("\n5. 提取嵌套字段:")
	incompleteJSON5 := `{"user": {"name": "Bob", "email": "bob@exam`
	if value, found := ExtractNestedValue(incompleteJSON5, "user", "name"); found {
		fmt.Printf("   user.name: %s (完整)\n", value)
	}
	if value, found := ExtractNestedValue(incompleteJSON5, "user", "email"); found {
		fmt.Printf("   user.email: %s (不完整)\n", value)
	}

	// 测试案例 6: 实际流式场景模拟
	fmt.Println("\n6. 模拟流式接收数据:")
	streamChunks := []string{
		`{"id": 1, "message": "`,
		`这是一段很长的消息内容`,
		`，正在逐步接收中...`,
		`"，"timestamp": 16`,
	}

	accumulated := ""
	for i, chunk := range streamChunks {
		accumulated += chunk
		fmt.Printf("   收到第 %d 块数据: %s\n", i+1, chunk)

		if value, found := ExtractIncompleteValue(accumulated, "message"); found {
			fmt.Printf("   -> 当前 message 值: %s\n", value)
		}
	}

	fmt.Println("\n=== 使用方法总结 ===")
	fmt.Println("jsonparser 无法处理不完整的 JSON，")
	fmt.Println("所以我们需要手动实现字符串解析来提取不完整字段。")
	fmt.Println("上面的 ExtractIncompleteValue 函数可以:")
	fmt.Println("  - 从不完整的 JSON 中提取指定 key 的值")
	fmt.Println("  - 处理字符串、数字、布尔值等类型")
	fmt.Println("  - 处理转义字符")
	fmt.Println("  - 即使值不完整也能返回已接收到的部分")
}

// ExtractIncompleteValue 从不完整的 JSON 中提取指定 key 的值（即使值不完整）
func ExtractIncompleteValue(jsonData, targetKey string) (string, bool) {
	// 查找目标 key（带引号）
	keyPattern := fmt.Sprintf(`"%s"`, targetKey)
	keyIndex := strings.Index(jsonData, keyPattern)
	if keyIndex == -1 {
		return "", false
	}

	// 找到 key 后面的冒号
	colonIndex := strings.Index(jsonData[keyIndex:], ":")
	if colonIndex == -1 {
		return "", false
	}

	// 跳过冒号和空白字符
	startIndex := keyIndex + colonIndex + 1
	for startIndex < len(jsonData) && isWhitespace(jsonData[startIndex]) {
		startIndex++
	}

	if startIndex >= len(jsonData) {
		return "", false
	}

	// 判断值的类型并提取
	switch jsonData[startIndex] {
	case '"':
		// 字符串类型
		return extractStringValue(jsonData[startIndex+1:]), true
	case '{':
		// 对象类型
		return extractUntilMatchingBrace(jsonData[startIndex:]), true
	case '[':
		// 数组类型
		return extractUntilMatchingBracket(jsonData[startIndex:]), true
	default:
		// 数字、布尔值、null
		return extractPrimitiveValue(jsonData[startIndex:]), true
	}
}

// ExtractNestedValue 提取嵌套字段（支持一层嵌套）
func ExtractNestedValue(jsonData string, parentKey, childKey string) (string, bool) {
	// 先找到父对象
	parentPattern := fmt.Sprintf(`"%s"`, parentKey)
	parentIndex := strings.Index(jsonData, parentPattern)
	if parentIndex == -1 {
		return "", false
	}

	// 找到父对象的开始位置
	colonIndex := strings.Index(jsonData[parentIndex:], ":")
	if colonIndex == -1 {
		return "", false
	}

	startIndex := parentIndex + colonIndex + 1
	for startIndex < len(jsonData) && isWhitespace(jsonData[startIndex]) {
		startIndex++
	}

	if startIndex >= len(jsonData) || jsonData[startIndex] != '{' {
		return "", false
	}

	// 在父对象内查找子字段
	return ExtractIncompleteValue(jsonData[startIndex:], childKey)
}

// extractStringValue 提取字符串值（处理转义，支持不完整）
func extractStringValue(data string) string {
	var result strings.Builder
	escaped := false

	for i := 0; i < len(data); i++ {
		ch := data[i]

		if escaped {
			result.WriteByte(ch)
			escaped = false
			continue
		}

		if ch == '\\' {
			escaped = true
			result.WriteByte(ch)
			continue
		}

		if ch == '"' {
			// 遇到未转义的引号，字符串结束
			break
		}

		result.WriteByte(ch)
	}

	return result.String()
}

// extractPrimitiveValue 提取原始值（数字、布尔、null）
func extractPrimitiveValue(data string) string {
	var result strings.Builder

	for i := 0; i < len(data); i++ {
		ch := data[i]

		// 遇到这些字符表示值结束
		if ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' {
			break
		}

		if !isWhitespace(ch) {
			result.WriteByte(ch)
		} else if result.Len() > 0 {
			// 如果已经开始收集内容，遇到空白字符就停止
			break
		}
	}

	return result.String()
}

// extractUntilMatchingBrace 提取到匹配的 } 为止
func extractUntilMatchingBrace(data string) string {
	level := 0
	for i := 0; i < len(data); i++ {
		switch data[i] {
		case '{':
			level++
		case '}':
			level--
			if level == 0 {
				return data[:i+1]
			}
		}
	}
	return data // 返回全部（不完整）
}

// extractUntilMatchingBracket 提取到匹配的 ] 为止
func extractUntilMatchingBracket(data string) string {
	level := 0
	for i := 0; i < len(data); i++ {
		switch data[i] {
		case '[':
			level++
		case ']':
			level--
			if level == 0 {
				return data[:i+1]
			}
		}
	}
	return data // 返回全部（不完整）
}

// isWhitespace 判断是否为空白字符
func isWhitespace(ch byte) bool {
	return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'
}

func sample() {
	// 示例 JSON 数据
	data := []byte(`{
		"person": {
			"name": {
				"first": "张",
				"last": "三"
			},
			"age": 30,
			"github": "https://github.com/zhangsan",
			"email": "zhangsan@example.com"
		},
		"company": "Example Corp",
		"skills": ["Go", "Python", "JavaScript"],
		"scores": [85, 92, 78, 95],
		"active": true,
		"balance": 1234.56,
		"metadata": null,
		"tags": {
			"level": "senior",
			"department": "engineering"
		}
	}`)

	fmt.Println("=== buger/jsonparser API 示例 ===")
	fmt.Println()

	// 1. Get() - 获取字符串值（返回 value, dataType, offset, err）
	fmt.Println("1. Get() - 获取简单值")
	if value, dataType, _, err := jsonparser.Get(data, "company"); err == nil {
		fmt.Printf("   company: %s (类型: %s)\n", string(value), dataType)
	}

	// 2. 获取嵌套对象的值
	fmt.Println("\n2. Get() - 获取嵌套对象的值")
	if firstName, _, _, err := jsonparser.Get(data, "person", "name", "first"); err == nil {
		fmt.Printf("   first name: %s\n", string(firstName))
	}
	if lastName, _, _, err := jsonparser.Get(data, "person", "name", "last"); err == nil {
		fmt.Printf("   last name: %s\n", string(lastName))
	}

	// 3. GetInt() - 获取整数值
	fmt.Println("\n3. GetInt() - 获取整数值")
	if age, err := jsonparser.GetInt(data, "person", "age"); err == nil {
		fmt.Printf("   age: %d 岁\n", age)
	}

	// 4. GetFloat() - 获取浮点数值
	fmt.Println("\n4. GetFloat() - 获取浮点数值")
	if balance, err := jsonparser.GetFloat(data, "balance"); err == nil {
		fmt.Printf("   balance: ¥%.2f\n", balance)
	}

	// 5. GetBoolean() - 获取布尔值
	fmt.Println("\n5. GetBoolean() - 获取布尔值")
	if active, err := jsonparser.GetBoolean(data, "active"); err == nil {
		fmt.Printf("   active: %t\n", active)
	}

	// 6. ArrayEach() - 遍历字符串数组
	fmt.Println("\n6. ArrayEach() - 遍历数组")
	fmt.Print("   skills: ")
	jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
		fmt.Printf("%s ", string(value))
	}, "skills")
	fmt.Println()

	// 7. 遍历数字数组并计算总和
	fmt.Println("\n7. ArrayEach() - 处理数字数组")
	var total int64
	var count int
	jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
		if num, err := jsonparser.ParseInt(value); err == nil {
			total += num
			count++
			fmt.Printf("     [%d] = %d\n", count-1, num)
		}
	}, "scores")
	if count > 0 {
		fmt.Printf("   统计: 总和=%d, 平均分=%.2f\n", total, float64(total)/float64(count))
	}

	// 8. GetUnsafeString() - 获取字符串（零拷贝，性能最好）
	fmt.Println("\n8. GetUnsafeString() - 高性能字符串获取（零拷贝）")
	if github, err := jsonparser.GetUnsafeString(data, "person", "github"); err == nil {
		fmt.Printf("   github: %s\n", github)
	}
	fmt.Println("   注意: GetUnsafeString 返回的字符串指向原始 JSON 数据，不会分配新内存")

	// 9. ObjectEach() - 遍历对象的所有键值对
	fmt.Println("\n9. ObjectEach() - 遍历对象")
	fmt.Println("   person.name 的所有字段:")
	jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
		fmt.Printf("     %s: %s (类型: %s)\n", string(key), string(value), dataType)
		return nil
	}, "person", "name")

	// 10. Set() - 设置/修改值
	fmt.Println("\n10. Set() - 修改 JSON 值")
	newData, err := jsonparser.Set(data, []byte(`"Example Tech Inc."`), "company")
	if err == nil {
		if company, _, _, err2 := jsonparser.Get(newData, "company"); err2 == nil {
			fmt.Printf("   修改后的 company: %s\n", string(company))
		}
	}

	// 11. Delete() - 删除键
	fmt.Println("\n11. Delete() - 删除键")
	newData = jsonparser.Delete(data, "metadata")
	fmt.Println("   已删除 metadata 字段")
	// 验证删除
	if _, _, _, err := jsonparser.Get(newData, "metadata"); err != nil {
		fmt.Printf("   验证: metadata 已不存在 (%v)\n", err)
	}

	// 12. GetString() - 直接获取字符串（会分配新内存）
	fmt.Println("\n12. GetString() - 获取字符串值")
	if company, err := jsonparser.GetString(data, "company"); err == nil {
		fmt.Printf("   company: %s\n", company)
	}
	if email, err := jsonparser.GetString(data, "person", "email"); err == nil {
		fmt.Printf("   email: %s\n", email)
	}

	// 13. EachKey() - 批量获取多个键（高性能，只遍历一次 JSON）
	fmt.Println("\n13. EachKey() - 批量获取多个键（一次遍历）")
	paths := [][]string{
		{"company"},
		{"person", "age"},
		{"active"},
		{"balance"},
	}
	jsonparser.EachKey(data, func(idx int, value []byte, vt jsonparser.ValueType, err error) {
		switch idx {
		case 0:
			fmt.Printf("   company: %s\n", string(value))
		case 1:
			fmt.Printf("   age: %s\n", string(value))
		case 2:
			fmt.Printf("   active: %s\n", string(value))
		case 3:
			fmt.Printf("   balance: %s\n", string(value))
		}
	}, paths...)
	fmt.Println("   注意: EachKey 比多次调用 Get 更高效")

	// 14. 数据类型检查 - Get 返回 4 个值
	fmt.Println("\n14. Get() 返回值详解")
	value, dataType, offset, err := jsonparser.Get(data, "person", "age")
	if err == nil {
		fmt.Printf("   值: %s\n", string(value))
		fmt.Printf("   类型: %s\n", dataType)
		fmt.Printf("   偏移量: %d\n", offset)
		fmt.Println("   注意: Get 返回 (value []byte, dataType ValueType, offset int, err error)")
	}

	// 15. 处理数组中的对象
	fmt.Println("\n15. 处理复杂的嵌套结构")
	complexData := []byte(`{
		"users": [
			{"id": 1, "name": "Alice", "role": "admin"},
			{"id": 2, "name": "Bob", "role": "user"},
			{"id": 3, "name": "Charlie", "role": "user"}
		]
	}`)
	fmt.Println("   users:")
	jsonparser.ArrayEach(complexData, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
		id, _ := jsonparser.GetInt(value, "id")
		name, _ := jsonparser.GetString(value, "name")
		role, _ := jsonparser.GetString(value, "role")
		fmt.Printf("     ID: %d, Name: %-8s, Role: %s\n", id, name, role)
	}, "users")

	// 16. 错误处理示例
	fmt.Println("\n16. 错误处理")
	if _, _, _, err := jsonparser.Get(data, "nonexistent"); err != nil {
		fmt.Printf("   尝试获取不存在的键: %v\n", err)
	}

	// 17. 处理 null 值
	fmt.Println("\n17. 处理 null 值")
	if _, dataType, _, err := jsonparser.Get(data, "metadata"); err == nil {
		if dataType == jsonparser.Null {
			fmt.Printf("   metadata 是 null 值 (类型: %s)\n", dataType)
		}
	}

	// 18. ObjectEach 遍历整个对象
	fmt.Println("\n18. ObjectEach() - 遍历 tags 对象的所有字段")
	jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
		fmt.Printf("   %s: %s\n", string(key), string(value))
		return nil
	}, "tags")

	// 19. 使用 ParseInt 和 ParseFloat
	fmt.Println("\n19. ParseInt/ParseFloat - 解析字节数组")
	ageBytes, _, _, _ := jsonparser.Get(data, "person", "age")
	if ageInt, err := jsonparser.ParseInt(ageBytes); err == nil {
		fmt.Printf("   ParseInt: age = %d\n", ageInt)
	}
	balanceBytes, _, _, _ := jsonparser.Get(data, "balance")
	if balanceFloat, err := jsonparser.ParseFloat(balanceBytes); err == nil {
		fmt.Printf("   ParseFloat: balance = %.2f\n", balanceFloat)
	}

	// 20. 判断数据类型
	fmt.Println("\n20. ValueType - 所有数据类型")
	checkType(data, "person", "name", "first") // String
	checkType(data, "person", "age")           // Number
	checkType(data, "active")                  // Boolean
	checkType(data, "metadata")                // Null
	checkType(data, "skills")                  // Array
	checkType(data, "person")                  // Object

	fmt.Println("\n=== 示例完成 ===")
	fmt.Println("\n性能提示:")
	fmt.Println("  - GetUnsafeString: 零拷贝，最快，但返回的字符串生命周期与原始数据相同")
	fmt.Println("  - GetString: 分配新内存，安全，但稍慢")
	fmt.Println("  - EachKey: 批量获取多个键时，只遍历一次 JSON，比多次 Get 快")
	fmt.Println("  - ArrayEach/ObjectEach: 流式处理，内存占用小")
}

// checkType 辅助函数：检查并打印数据类型
func checkType(data []byte, keys ...string) {
	if _, dataType, _, err := jsonparser.Get(data, keys...); err == nil {
		path := keys[0]
		for i := 1; i < len(keys); i++ {
			path += "." + keys[i]
		}

		var typeName string
		switch dataType {
		case jsonparser.String:
			typeName = "String (字符串)"
		case jsonparser.Number:
			typeName = "Number (数字)"
		case jsonparser.Object:
			typeName = "Object (对象)"
		case jsonparser.Array:
			typeName = "Array (数组)"
		case jsonparser.Boolean:
			typeName = "Boolean (布尔)"
		case jsonparser.Null:
			typeName = "Null (空值)"
		case jsonparser.Unknown:
			typeName = "Unknown (未知)"
		default:
			typeName = "NotExist (不存在)"
		}

		fmt.Printf("   %s -> %s\n", path, typeName)
	}
}
