package fileinit_test

import (
	"bytes"
	"compress/gzip"
	"io/ioutil"
	"testing"

	proto "github.com/golang/protobuf/proto"
	"google.golang.org/protobuf/reflect/protodesc"
	"google.golang.org/protobuf/reflect/protoreflect"

	testpb "google.golang.org/protobuf/internal/testprotos/test"
	"google.golang.org/protobuf/types/descriptorpb"
)

func TestInit(t *testing.T) {
	// Compare the FileDescriptorProto for the same test file from two different sources:
	//
	// 1. The result of passing the fileinit-produced FileDescriptor through protodesc.
	// 2. The protoc-generated wire-encoded message.
	//
	// This serves as a test of both fileinit and protodesc.
	got := protodesc.ToFileDescriptorProto(testpb.File_test_test_proto)

	want := &descriptorpb.FileDescriptorProto{}
	zb, _ := (&testpb.TestAllTypes{}).Descriptor()
	r, _ := gzip.NewReader(bytes.NewBuffer(zb))
	b, _ := ioutil.ReadAll(r)
	if err := proto.Unmarshal(b, want); err != nil {
		t.Fatal(err)
	}

	if !proto.Equal(got, want) {
		t.Errorf("protodesc.ToFileDescriptorProto(testpb.Test_protoFile) is not equal to the protoc-generated FileDescriptorProto for internal/testprotos/test/test.proto")
	}

	// Verify that the test proto file provides exhaustive coverage of all descriptor fields.
	seen := make(map[protoreflect.FullName]bool)
	visitFields(want.ProtoReflect(), func(field protoreflect.FieldDescriptor) {
		seen[field.FullName()] = true
	})
	ignore := map[protoreflect.FullName]bool{
		// The protoreflect descriptors don't include source info.
		"google.protobuf.FileDescriptorProto.source_code_info": true,
		"google.protobuf.FileDescriptorProto.syntax":           true,

		// TODO: Test oneof and extension options. Testing these requires extending the
		// options messages (because they contain no user-settable fields), but importing
		// decriptor.proto from test.proto currently causes an import cycle. Add test
		// cases when that import cycle has been fixed.
		"google.protobuf.OneofDescriptorProto.options": true,
	}
	for _, messageName := range []protoreflect.Name{
		"FileDescriptorProto",
		"DescriptorProto",
		"FieldDescriptorProto",
		"OneofDescriptorProto",
		"EnumDescriptorProto",
		"EnumValueDescriptorProto",
		"ServiceDescriptorProto",
		"MethodDescriptorProto",
	} {
		message := descriptorpb.File_google_protobuf_descriptor_proto.Messages().ByName(messageName)
		for i, fields := 0, message.Fields(); i < fields.Len(); i++ {
			if name := fields.Get(i).FullName(); !seen[name] && !ignore[name] {
				t.Errorf("No test for descriptor field: %v", name)
			}
		}
	}

	// Verify that message descriptors for map entries have no Go type info.
	mapEntryName := protoreflect.FullName("goproto.proto.test.TestAllTypes.MapInt32Int32Entry")
	d := testpb.File_test_test_proto.Messages().ByName("TestAllTypes").Fields().ByName("map_int32_int32").Message()
	if gotName, wantName := d.FullName(), mapEntryName; gotName != wantName {
		t.Fatalf("looked up wrong descriptor: got %v, want %v", gotName, wantName)
	}
	if _, ok := d.(protoreflect.MessageType); ok {
		t.Errorf("message descriptor for %v must not implement protoreflect.MessageType", mapEntryName)
	}
}

// visitFields calls f for every field set in m and its children.
func visitFields(m protoreflect.Message, f func(protoreflect.FieldDescriptor)) {
	fieldDescs := m.Descriptor().Fields()
	k := m.KnownFields()
	k.Range(func(num protoreflect.FieldNumber, value protoreflect.Value) bool {
		field := fieldDescs.ByNumber(num)
		f(field)
		switch field.Kind() {
		case protoreflect.MessageKind, protoreflect.GroupKind:
			if field.IsList() {
				for i, list := 0, value.List(); i < list.Len(); i++ {
					visitFields(list.Get(i).Message(), f)
				}
			} else {
				visitFields(value.Message(), f)
			}
		}
		return true
	})
}

func TestWeakInit(t *testing.T) {
	file := testpb.File_test_test_proto
	fd := file.Messages().ByName("TestWeak").Fields().ByName("weak_message")
	if want, got := fd.IsWeak(), true; got != want {
		t.Errorf("field %v: IsWeak() = %v, want %v", fd.FullName(), want, got)
	}
	if want, got := fd.Message().IsPlaceholder(), false; got != want {
		t.Errorf("field %v: Message.IsPlaceholder() = %v, want %v", fd.FullName(), want, got)
	}
	if fd.Message().Fields().Len() == 0 {
		t.Errorf("field %v: Message().Fields().Len() == 0, want >0", fd.FullName())
	}
}
