// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Go native fuzzing was added in go1.18. Remove this once we stop supporting
// go1.17.
//go:build go1.18

package protojson_test

import (
	"math"
	"testing"

	"github.com/google/go-cmp/cmp"
	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/testing/protocmp"

	testfuzzpb "google.golang.org/protobuf/internal/testprotos/editionsfuzztest"
)

// roundTripAndCompareProto tests if a protojson.Marshal/Unmarshal roundtrip
// preserves the contents of the message. Note: wireBytes are a protocol
// buffer wire format message, not the JSON formatted proto. We do this because
// a random stream of bytes (e.g. generated by the fuzz engine) is more likely
// to be valid proto wire format than that it is valid json format.
func roundTripAndCompareProto(t *testing.T, wireBytes []byte, messages ...proto.Message) {
	for _, msg := range messages {
		src := msg.ProtoReflect().Type().New().Interface()

		if err := proto.Unmarshal(wireBytes, src); err != nil {
			// Ignoring invalid wire format since we want to test the protojson
			// implementation, not the wireformat implementation.
			return
		}

		// Unknown fields are not marshaled by protojson so we strip them.
		src.ProtoReflect().SetUnknown(nil)
		var ranger func(protoreflect.FieldDescriptor, protoreflect.Value) bool
		stripUnknown := func(m protoreflect.Message) {
			m.SetUnknown(nil)
			m.Range(ranger)
		}
		ranger = func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
			switch {
			case fd.IsMap():
				if fd.MapValue().Message() != nil {
					v.Map().Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool {
						stripUnknown(v.Message())
						return true
					})
				}
			case fd.Message() != nil:
				if fd.Cardinality() == protoreflect.Repeated {
					l := v.List()
					for i := 0; i < l.Len(); i++ {
						stripUnknown(l.Get(i).Message())
					}
				} else {
					stripUnknown(v.Message())
				}
			}
			return true
		}
		stripUnknown(src.ProtoReflect())

		jsonBytes, err := protojson.Marshal(src)
		if err != nil {
			t.Errorf("failed to marshal messsage to json: %v\nmessage: %v", err, src)
		}
		dst := msg.ProtoReflect().Type().New().Interface()

		if err := protojson.Unmarshal(jsonBytes, dst); err != nil {
			t.Errorf("failed to unmarshal messsage from json: %v\njson: %s", err, jsonBytes)
		}

		// The cmp package does not deal with NaN on its own and will report
		// NaN != NaN.
		optNaN64 := cmp.Comparer(func(x, y float32) bool {
			return (math.IsNaN(float64(x)) && math.IsNaN(float64(y))) || x == y
		})
		optNaN32 := cmp.Comparer(func(x, y float64) bool {
			return (math.IsNaN(x) && math.IsNaN(y)) || x == y
		})
		if diff := cmp.Diff(src, dst, protocmp.Transform(), optNaN64, optNaN32); diff != "" {
			t.Error(diff)
		}
	}
}

func FuzzEncodeDecodeRoundTrip(f *testing.F) {
	f.Add([]byte("Hello World!"))
	f.Fuzz(func(t *testing.T, in []byte) {
		// We cannot test proto2 because it does not have UTF-8 validation
		// but the JSON spec requires valid UTF-8 and thus we might initialize
		// proto2 messages with invalid UTF-8 and then fail marshalling it.
		roundTripAndCompareProto(t, in, (*testfuzzpb.TestAllTypesProto3)(nil), (*testfuzzpb.TestAllTypesProto3Editions)(nil))
	})
}
