// Copyright 2019 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.

package prototext_test

import (
	"testing"

	"google.golang.org/protobuf/encoding/prototext"
	"google.golang.org/protobuf/proto"
	preg "google.golang.org/protobuf/reflect/protoregistry"

	"google.golang.org/protobuf/encoding/testprotos/pb2"
	"google.golang.org/protobuf/types/known/anypb"
	"google.golang.org/protobuf/types/known/durationpb"
	"google.golang.org/protobuf/types/known/emptypb"
	"google.golang.org/protobuf/types/known/structpb"
	"google.golang.org/protobuf/types/known/timestamppb"
	"google.golang.org/protobuf/types/known/wrapperspb"
)

func TestRoundTrip(t *testing.T) {
	tests := []struct {
		desc     string
		resolver *preg.Types
		message  proto.Message
	}{{
		desc: "well-known type fields set to empty messages",
		message: &pb2.KnownTypes{
			OptBool:      &wrapperspb.BoolValue{},
			OptInt32:     &wrapperspb.Int32Value{},
			OptInt64:     &wrapperspb.Int64Value{},
			OptUint32:    &wrapperspb.UInt32Value{},
			OptUint64:    &wrapperspb.UInt64Value{},
			OptFloat:     &wrapperspb.FloatValue{},
			OptDouble:    &wrapperspb.DoubleValue{},
			OptString:    &wrapperspb.StringValue{},
			OptBytes:     &wrapperspb.BytesValue{},
			OptDuration:  &durationpb.Duration{},
			OptTimestamp: &timestamppb.Timestamp{},
			OptStruct:    &structpb.Struct{},
			OptList:      &structpb.ListValue{},
			OptValue:     &structpb.Value{},
			OptEmpty:     &emptypb.Empty{},
			OptAny:       &anypb.Any{},
		},
	}, {
		desc: "well-known type scalar fields",
		message: &pb2.KnownTypes{
			OptBool: &wrapperspb.BoolValue{
				Value: true,
			},
			OptInt32: &wrapperspb.Int32Value{
				Value: -42,
			},
			OptInt64: &wrapperspb.Int64Value{
				Value: -42,
			},
			OptUint32: &wrapperspb.UInt32Value{
				Value: 0xff,
			},
			OptUint64: &wrapperspb.UInt64Value{
				Value: 0xffff,
			},
			OptFloat: &wrapperspb.FloatValue{
				Value: 1.234,
			},
			OptDouble: &wrapperspb.DoubleValue{
				Value: 1.23e308,
			},
			OptString: &wrapperspb.StringValue{
				Value: "谷歌",
			},
			OptBytes: &wrapperspb.BytesValue{
				Value: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
			},
		},
	}, {
		desc: "well-known type time-related fields",
		message: &pb2.KnownTypes{
			OptDuration: &durationpb.Duration{
				Seconds: -3600,
				Nanos:   -123,
			},
			OptTimestamp: &timestamppb.Timestamp{
				Seconds: 1257894000,
				Nanos:   123,
			},
		},
	}, {
		desc: "Struct field and different Value types",
		message: &pb2.KnownTypes{
			OptStruct: &structpb.Struct{
				Fields: map[string]*structpb.Value{
					"bool": &structpb.Value{
						Kind: &structpb.Value_BoolValue{
							BoolValue: true,
						},
					},
					"double": &structpb.Value{
						Kind: &structpb.Value_NumberValue{
							NumberValue: 3.1415,
						},
					},
					"null": &structpb.Value{
						Kind: &structpb.Value_NullValue{
							NullValue: structpb.NullValue_NULL_VALUE,
						},
					},
					"string": &structpb.Value{
						Kind: &structpb.Value_StringValue{
							StringValue: "string",
						},
					},
					"struct": &structpb.Value{
						Kind: &structpb.Value_StructValue{
							StructValue: &structpb.Struct{
								Fields: map[string]*structpb.Value{
									"bool": &structpb.Value{
										Kind: &structpb.Value_BoolValue{
											BoolValue: false,
										},
									},
								},
							},
						},
					},
					"list": &structpb.Value{
						Kind: &structpb.Value_ListValue{
							ListValue: &structpb.ListValue{
								Values: []*structpb.Value{
									{
										Kind: &structpb.Value_BoolValue{
											BoolValue: false,
										},
									},
									{
										Kind: &structpb.Value_StringValue{
											StringValue: "hello",
										},
									},
								},
							},
						},
					},
				},
			},
		},
	}, {
		desc:     "Any field without registered type",
		resolver: new(preg.Types),
		message: func() proto.Message {
			m := &pb2.Nested{
				OptString: proto.String("embedded inside Any"),
				OptNested: &pb2.Nested{
					OptString: proto.String("inception"),
				},
			}
			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
			if err != nil {
				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
			}
			return &pb2.KnownTypes{
				OptAny: &anypb.Any{
					TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
					Value:   b,
				},
			}
		}(),
	}, {
		desc: "Any field with registered type",
		message: func() *pb2.KnownTypes {
			m := &pb2.Nested{
				OptString: proto.String("embedded inside Any"),
				OptNested: &pb2.Nested{
					OptString: proto.String("inception"),
				},
			}
			b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
			if err != nil {
				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
			}
			return &pb2.KnownTypes{
				OptAny: &anypb.Any{
					TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
					Value:   b,
				},
			}
		}(),
	}, {
		desc: "Any field containing Any message",
		message: func() *pb2.KnownTypes {
			m1 := &pb2.Nested{
				OptString: proto.String("message inside Any of another Any field"),
			}
			b1, err := proto.MarshalOptions{Deterministic: true}.Marshal(m1)
			if err != nil {
				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
			}
			m2 := &anypb.Any{
				TypeUrl: "pb2.Nested",
				Value:   b1,
			}
			b2, err := proto.MarshalOptions{Deterministic: true}.Marshal(m2)
			if err != nil {
				t.Fatalf("error in binary marshaling message for Any.value: %v", err)
			}
			return &pb2.KnownTypes{
				OptAny: &anypb.Any{
					TypeUrl: "google.protobuf.Any",
					Value:   b2,
				},
			}
		}(),
	}}

	for _, tt := range tests {
		tt := tt
		t.Run(tt.desc, func(t *testing.T) {
			t.Parallel()
			b, err := prototext.MarshalOptions{Resolver: tt.resolver}.Marshal(tt.message)
			if err != nil {
				t.Errorf("Marshal() returned error: %v\n\n", err)
			}

			gotMessage := new(pb2.KnownTypes)
			err = prototext.UnmarshalOptions{Resolver: tt.resolver}.Unmarshal(b, gotMessage)
			if err != nil {
				t.Errorf("Unmarshal() returned error: %v\n\n", err)
			}

			if !proto.Equal(gotMessage, tt.message) {
				t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", gotMessage, tt.message)
			}
		})
	}
}
