// 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 protodesc

import (
	"fmt"
	"strings"

	"google.golang.org/protobuf/internal/encoding/defval"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"

	"google.golang.org/protobuf/types/descriptorpb"
)

// ToFileDescriptorProto copies a protoreflect.FileDescriptor into a
// google.protobuf.FileDescriptorProto message.
func ToFileDescriptorProto(file protoreflect.FileDescriptor) *descriptorpb.FileDescriptorProto {
	p := &descriptorpb.FileDescriptorProto{
		Name:    proto.String(file.Path()),
		Package: proto.String(string(file.Package())),
		Options: proto.Clone(file.Options()).(*descriptorpb.FileOptions),
	}
	for i, imports := 0, file.Imports(); i < imports.Len(); i++ {
		imp := imports.Get(i)
		p.Dependency = append(p.Dependency, imp.Path())
		if imp.IsPublic {
			p.PublicDependency = append(p.PublicDependency, int32(i))
		}
		if imp.IsWeak {
			p.WeakDependency = append(p.WeakDependency, int32(i))
		}
	}
	for i, locs := 0, file.SourceLocations(); i < locs.Len(); i++ {
		loc := locs.Get(i)
		l := &descriptorpb.SourceCodeInfo_Location{}
		l.Path = append(l.Path, loc.Path...)
		if loc.StartLine == loc.EndLine {
			l.Span = []int32{int32(loc.StartLine), int32(loc.StartColumn), int32(loc.EndColumn)}
		} else {
			l.Span = []int32{int32(loc.StartLine), int32(loc.StartColumn), int32(loc.EndLine), int32(loc.EndColumn)}
		}
		l.LeadingDetachedComments = append([]string(nil), loc.LeadingDetachedComments...)
		if loc.LeadingComments != "" {
			l.LeadingComments = proto.String(loc.LeadingComments)
		}
		if loc.TrailingComments != "" {
			l.TrailingComments = proto.String(loc.TrailingComments)
		}
		if p.SourceCodeInfo == nil {
			p.SourceCodeInfo = &descriptorpb.SourceCodeInfo{}
		}
		p.SourceCodeInfo.Location = append(p.SourceCodeInfo.Location, l)

	}
	for i, messages := 0, file.Messages(); i < messages.Len(); i++ {
		p.MessageType = append(p.MessageType, ToDescriptorProto(messages.Get(i)))
	}
	for i, enums := 0, file.Enums(); i < enums.Len(); i++ {
		p.EnumType = append(p.EnumType, ToEnumDescriptorProto(enums.Get(i)))
	}
	for i, services := 0, file.Services(); i < services.Len(); i++ {
		p.Service = append(p.Service, ToServiceDescriptorProto(services.Get(i)))
	}
	for i, exts := 0, file.Extensions(); i < exts.Len(); i++ {
		p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i)))
	}
	if syntax := file.Syntax(); syntax != protoreflect.Proto2 {
		p.Syntax = proto.String(file.Syntax().String())
	}
	return p
}

// ToDescriptorProto copies a protoreflect.MessageDescriptor into a
// google.protobuf.DescriptorProto message.
func ToDescriptorProto(message protoreflect.MessageDescriptor) *descriptorpb.DescriptorProto {
	p := &descriptorpb.DescriptorProto{
		Name:    proto.String(string(message.Name())),
		Options: proto.Clone(message.Options()).(*descriptorpb.MessageOptions),
	}
	for i, fields := 0, message.Fields(); i < fields.Len(); i++ {
		p.Field = append(p.Field, ToFieldDescriptorProto(fields.Get(i)))
	}
	for i, exts := 0, message.Extensions(); i < exts.Len(); i++ {
		p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i)))
	}
	for i, messages := 0, message.Messages(); i < messages.Len(); i++ {
		p.NestedType = append(p.NestedType, ToDescriptorProto(messages.Get(i)))
	}
	for i, enums := 0, message.Enums(); i < enums.Len(); i++ {
		p.EnumType = append(p.EnumType, ToEnumDescriptorProto(enums.Get(i)))
	}
	for i, xranges := 0, message.ExtensionRanges(); i < xranges.Len(); i++ {
		xrange := xranges.Get(i)
		p.ExtensionRange = append(p.ExtensionRange, &descriptorpb.DescriptorProto_ExtensionRange{
			Start:   proto.Int32(int32(xrange[0])),
			End:     proto.Int32(int32(xrange[1])),
			Options: proto.Clone(message.ExtensionRangeOptions(i)).(*descriptorpb.ExtensionRangeOptions),
		})
	}
	for i, oneofs := 0, message.Oneofs(); i < oneofs.Len(); i++ {
		p.OneofDecl = append(p.OneofDecl, ToOneofDescriptorProto(oneofs.Get(i)))
	}
	for i, ranges := 0, message.ReservedRanges(); i < ranges.Len(); i++ {
		rrange := ranges.Get(i)
		p.ReservedRange = append(p.ReservedRange, &descriptorpb.DescriptorProto_ReservedRange{
			Start: proto.Int32(int32(rrange[0])),
			End:   proto.Int32(int32(rrange[1])),
		})
	}
	for i, names := 0, message.ReservedNames(); i < names.Len(); i++ {
		p.ReservedName = append(p.ReservedName, string(names.Get(i)))
	}
	return p
}

// ToFieldDescriptorProto copies a protoreflect.FieldDescriptor into a
// google.protobuf.FieldDescriptorProto message.
func ToFieldDescriptorProto(field protoreflect.FieldDescriptor) *descriptorpb.FieldDescriptorProto {
	p := &descriptorpb.FieldDescriptorProto{
		Name:    proto.String(string(field.Name())),
		Number:  proto.Int32(int32(field.Number())),
		Label:   descriptorpb.FieldDescriptorProto_Label(field.Cardinality()).Enum(),
		Options: proto.Clone(field.Options()).(*descriptorpb.FieldOptions),
	}
	if field.IsExtension() {
		p.Extendee = fullNameOf(field.ContainingMessage())
	}
	if field.Kind().IsValid() {
		p.Type = descriptorpb.FieldDescriptorProto_Type(field.Kind()).Enum()
	}
	if field.Enum() != nil {
		p.TypeName = fullNameOf(field.Enum())
	}
	if field.Message() != nil {
		p.TypeName = fullNameOf(field.Message())
	}
	if field.HasJSONName() {
		p.JsonName = proto.String(field.JSONName())
	}
	if field.Syntax() == protoreflect.Proto3 && field.HasOptionalKeyword() {
		p.Proto3Optional = proto.Bool(true)
	}
	if field.HasDefault() {
		def, err := defval.Marshal(field.Default(), field.DefaultEnumValue(), field.Kind(), defval.Descriptor)
		if err != nil && field.DefaultEnumValue() != nil {
			def = string(field.DefaultEnumValue().Name()) // occurs for unresolved enum values
		} else if err != nil {
			panic(fmt.Sprintf("%v: %v", field.FullName(), err))
		}
		p.DefaultValue = proto.String(def)
	}
	if oneof := field.ContainingOneof(); oneof != nil {
		p.OneofIndex = proto.Int32(int32(oneof.Index()))
	}
	return p
}

// ToOneofDescriptorProto copies a protoreflect.OneofDescriptor into a
// google.protobuf.OneofDescriptorProto message.
func ToOneofDescriptorProto(oneof protoreflect.OneofDescriptor) *descriptorpb.OneofDescriptorProto {
	return &descriptorpb.OneofDescriptorProto{
		Name:    proto.String(string(oneof.Name())),
		Options: proto.Clone(oneof.Options()).(*descriptorpb.OneofOptions),
	}
}

// ToEnumDescriptorProto copies a protoreflect.EnumDescriptor into a
// google.protobuf.EnumDescriptorProto message.
func ToEnumDescriptorProto(enum protoreflect.EnumDescriptor) *descriptorpb.EnumDescriptorProto {
	p := &descriptorpb.EnumDescriptorProto{
		Name:    proto.String(string(enum.Name())),
		Options: proto.Clone(enum.Options()).(*descriptorpb.EnumOptions),
	}
	for i, values := 0, enum.Values(); i < values.Len(); i++ {
		p.Value = append(p.Value, ToEnumValueDescriptorProto(values.Get(i)))
	}
	for i, ranges := 0, enum.ReservedRanges(); i < ranges.Len(); i++ {
		rrange := ranges.Get(i)
		p.ReservedRange = append(p.ReservedRange, &descriptorpb.EnumDescriptorProto_EnumReservedRange{
			Start: proto.Int32(int32(rrange[0])),
			End:   proto.Int32(int32(rrange[1])),
		})
	}
	for i, names := 0, enum.ReservedNames(); i < names.Len(); i++ {
		p.ReservedName = append(p.ReservedName, string(names.Get(i)))
	}
	return p
}

// ToEnumValueDescriptorProto copies a protoreflect.EnumValueDescriptor into a
// google.protobuf.EnumValueDescriptorProto message.
func ToEnumValueDescriptorProto(value protoreflect.EnumValueDescriptor) *descriptorpb.EnumValueDescriptorProto {
	return &descriptorpb.EnumValueDescriptorProto{
		Name:    proto.String(string(value.Name())),
		Number:  proto.Int32(int32(value.Number())),
		Options: proto.Clone(value.Options()).(*descriptorpb.EnumValueOptions),
	}
}

// ToServiceDescriptorProto copies a protoreflect.ServiceDescriptor into a
// google.protobuf.ServiceDescriptorProto message.
func ToServiceDescriptorProto(service protoreflect.ServiceDescriptor) *descriptorpb.ServiceDescriptorProto {
	p := &descriptorpb.ServiceDescriptorProto{
		Name:    proto.String(string(service.Name())),
		Options: proto.Clone(service.Options()).(*descriptorpb.ServiceOptions),
	}
	for i, methods := 0, service.Methods(); i < methods.Len(); i++ {
		p.Method = append(p.Method, ToMethodDescriptorProto(methods.Get(i)))
	}
	return p
}

// ToMethodDescriptorProto copies a protoreflect.MethodDescriptor into a
// google.protobuf.MethodDescriptorProto message.
func ToMethodDescriptorProto(method protoreflect.MethodDescriptor) *descriptorpb.MethodDescriptorProto {
	p := &descriptorpb.MethodDescriptorProto{
		Name:       proto.String(string(method.Name())),
		InputType:  fullNameOf(method.Input()),
		OutputType: fullNameOf(method.Output()),
		Options:    proto.Clone(method.Options()).(*descriptorpb.MethodOptions),
	}
	if method.IsStreamingClient() {
		p.ClientStreaming = proto.Bool(true)
	}
	if method.IsStreamingServer() {
		p.ServerStreaming = proto.Bool(true)
	}
	return p
}

func fullNameOf(d protoreflect.Descriptor) *string {
	if d == nil {
		return nil
	}
	if strings.HasPrefix(string(d.FullName()), unknownPrefix) {
		return proto.String(string(d.FullName()[len(unknownPrefix):]))
	}
	return proto.String("." + string(d.FullName()))
}
