//go:build go1.18
// +build go1.18

/*
 * Copyright 2024 CloudWeGo Authors
 *
 * 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 utils

import (
	"encoding/json"
	"reflect"
	"testing"

	"github.com/bytedance/sonic"

	"github.com/cloudwego/kitex/internal/test"
)

func FuzzJSONStr2Map(f *testing.F) {
	mapInfo := prepareMap()
	jsonRet, _ := sonic.MarshalString(mapInfo)
	f.Add(`{}`)
	f.Add(`{"":""}`)
	f.Add(jsonRet)
	f.Add(`{"\u4f60\u597d": "\u5468\u6770\u4f26"}`)
	f.Add(`{"aaa\u4f60\u597daaa": ":\\\u5468\u6770\u4f26"  ,  "加油 \u52a0\u6cb9" : "Come on \u52a0\u6cb9"}`)
	f.Add(`{"\u4F60\u597D": "\uDFFF\uD800"}`)
	f.Add(`{"a":"b", "\x4F60\x597D": "\uDFqwdFF\uD800"}`)
	f.Fuzz(func(t *testing.T, data string) {
		if !json.Valid([]byte(data)) {
			return
		}
		map1, err1 := JSONStr2Map(data)
		map2, err2 := _JSONStr2Map(data)
		test.Assert(t, err1 == nil, data)
		test.Assert(t, err2 == nil, data)
		test.Assert(t, reflect.DeepEqual(map1, map2), data)
	})
}

func FuzzMap2JSON(f *testing.F) {
	mapInfo := prepareMap()
	jsonRet, _ := sonic.MarshalString(mapInfo)
	f.Add(`{}`)
	f.Add(`{"":""}`)
	f.Add(jsonRet)
	f.Add(`{"\u4f60\u597d": "\u5468\u6770\u4f26"}`)
	f.Add(`{"aaa\u4f60\u597daaa": ":\\\u5468\u6770\u4f26"  ,  "加油 \u52a0\u6cb9" : "Come on \u52a0\u6cb9"}`)
	f.Add(`{"\u4F60\u597D": "\uDFFF\uD800"}`)
	f.Add(`{"a":"b", "\x4F60\x597D": "\uDFqwdFF\uD800"}`)
	f.Fuzz(func(t *testing.T, data string) {
		var m map[string]string
		if err := json.Unmarshal([]byte(data), &m); err != nil {
			return
		}
		str1, err1 := Map2JSONStr(m)
		str2, err2 := _Map2JSONStr(m)
		test.Assert(t, err1 == nil, data)
		test.Assert(t, err2 == nil, data)
		test.Assert(t, len(str1) == len(str2))
		var m1, m2 map[string]string
		test.Assert(t, json.Unmarshal([]byte(str1), &m1) == nil)
		test.Assert(t, json.Unmarshal([]byte(str2), &m2) == nil)
		test.Assert(t, reflect.DeepEqual(m1, m2))
	})
}
