// Copyright 2018 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 impl

import (
	"reflect"
	"strconv"

	"google.golang.org/protobuf/encoding/prototext"
	pref "google.golang.org/protobuf/reflect/protoreflect"
)

// Export is a zero-length named type that exists only to export a set of
// functions that we do not want to appear in godoc.
type Export struct{}

// enum is any enum type generated by protoc-gen-go
// and must be a named int32 type.
type enum = interface{}

// EnumOf returns the protoreflect.Enum interface over e.
func (Export) EnumOf(e enum) pref.Enum {
	if ev, ok := e.(pref.Enum); ok {
		return ev
	}
	return legacyWrapper.EnumOf(e)
}

// EnumTypeOf returns the protoreflect.EnumType for e.
func (Export) EnumTypeOf(e enum) pref.EnumType {
	if ev, ok := e.(pref.Enum); ok {
		return &enumType{ev.Descriptor(), reflect.TypeOf(e)}
	}
	return legacyWrapper.EnumTypeOf(e)
}

// TODO: This needs to be centralized in a package.
type enumType struct {
	// TODO: Remove me as an embedded field.
	pref.EnumDescriptor
	typ reflect.Type // must implement protoreflect.Enum
}

func (t *enumType) Descriptor() pref.EnumDescriptor { return t.EnumDescriptor }
func (t *enumType) GoType() reflect.Type            { return t.typ }
func (t *enumType) New(n pref.EnumNumber) pref.Enum {
	return reflect.ValueOf(n).Convert(t.typ).Interface().(pref.Enum)
}

// EnumDescriptorOf returns the protoreflect.EnumDescriptor for e.
func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor {
	if ev, ok := e.(pref.Enum); ok {
		return ev.Descriptor()
	}
	return legacyWrapper.EnumDescriptorOf(e)
}

// EnumStringOf returns the enum value as a string, either as the name if
// the number is resolvable, or the number formatted as a string.
func (Export) EnumStringOf(ed pref.EnumDescriptor, n pref.EnumNumber) string {
	ev := ed.Values().ByNumber(n)
	if ev != nil {
		return string(ev.Name())
	}
	return strconv.Itoa(int(n))
}

// message is any message type generated by protoc-gen-go
// and must be a pointer to a named struct type.
type message = interface{}

// MessageOf returns the protoreflect.Message interface over m.
func (Export) MessageOf(m message) pref.Message {
	if mv, ok := m.(pref.ProtoMessage); ok {
		return mv.ProtoReflect()
	}
	return legacyWrapper.MessageOf(m)
}

// MessageTypeOf returns the protoreflect.MessageType for m.
func (Export) MessageTypeOf(m message) pref.MessageType {
	if mv, ok := m.(pref.ProtoMessage); ok {
		return &messageType{mv.ProtoReflect().Descriptor(), reflect.TypeOf(m)}
	}
	return legacyWrapper.MessageTypeOf(m)
}

// TODO: This needs to be centralized in a package.
type messageType struct {
	// TODO: Remove me as an embedded field.
	pref.MessageDescriptor
	typ reflect.Type // must implement protoreflect.ProtoMessage
}

func (t *messageType) Descriptor() pref.MessageDescriptor { return t.MessageDescriptor }
func (t *messageType) GoType() reflect.Type               { return t.typ }
func (t *messageType) New() pref.Message {
	return reflect.New(t.typ.Elem()).Interface().(pref.ProtoMessage).ProtoReflect()
}

// MessageDescriptorOf returns the protoreflect.MessageDescriptor for m.
func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor {
	if mv, ok := m.(pref.ProtoMessage); ok {
		return mv.ProtoReflect().Descriptor()
	}
	return legacyWrapper.MessageDescriptorOf(m)
}

// MessageStringOf returns the message value as a string,
// which is the message serialized in the protobuf text format.
func (Export) MessageStringOf(m pref.ProtoMessage) string {
	b, _ := prototext.MarshalOptions{AllowPartial: true}.Marshal(m)
	return string(b)
}
