// 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 (
	"fmt"
	"reflect"
	"sync"

	"google.golang.org/protobuf/internal/descfmt"
	ptag "google.golang.org/protobuf/internal/encoding/tag"
	"google.golang.org/protobuf/internal/filedesc"
	pvalue "google.golang.org/protobuf/internal/value"
	pref "google.golang.org/protobuf/reflect/protoreflect"
	preg "google.golang.org/protobuf/reflect/protoregistry"
	"google.golang.org/protobuf/reflect/prototype"
	piface "google.golang.org/protobuf/runtime/protoiface"
)

// legacyExtensionDescKey is a comparable version of protoiface.ExtensionDescV1
// suitable for use as a key in a map.
type legacyExtensionDescKey struct {
	typeV2        pref.ExtensionType
	extendedType  reflect.Type
	extensionType reflect.Type
	field         int32
	name          string
	tag           string
	filename      string
}

func legacyExtensionDescKeyOf(d *piface.ExtensionDescV1) legacyExtensionDescKey {
	return legacyExtensionDescKey{
		d.Type,
		reflect.TypeOf(d.ExtendedType),
		reflect.TypeOf(d.ExtensionType),
		d.Field, d.Name, d.Tag, d.Filename,
	}
}

var (
	legacyExtensionTypeCache sync.Map // map[legacyExtensionDescKey]protoreflect.ExtensionType
	legacyExtensionDescCache sync.Map // map[protoreflect.ExtensionType]*protoiface.ExtensionDescV1
)

// legacyExtensionDescFromType converts a v2 protoreflect.ExtensionType to a
// protoiface.ExtensionDescV1. The returned ExtensionDesc must not be mutated.
func legacyExtensionDescFromType(xt pref.ExtensionType) *piface.ExtensionDescV1 {
	// Fast-path: check whether an extension desc is already nested within.
	if xt, ok := xt.(interface {
		ProtoLegacyExtensionDesc() *piface.ExtensionDescV1
	}); ok {
		if d := xt.ProtoLegacyExtensionDesc(); d != nil {
			return d
		}
	}

	// Fast-path: check the cache for whether this ExtensionType has already
	// been converted to a legacy descriptor.
	if d, ok := legacyExtensionDescCache.Load(xt); ok {
		return d.(*piface.ExtensionDescV1)
	}

	// Determine the parent type if possible.
	var parent piface.MessageV1
	messageName := xt.Descriptor().ContainingMessage().FullName()
	if mt, _ := preg.GlobalTypes.FindMessageByName(messageName); mt != nil {
		// Create a new parent message and unwrap it if possible.
		mv := mt.New().Interface()
		t := reflect.TypeOf(mv)
		if mv, ok := mv.(pvalue.Unwrapper); ok {
			t = reflect.TypeOf(mv.ProtoUnwrap())
		}

		// Check whether the message implements the legacy v1 Message interface.
		mz := reflect.Zero(t).Interface()
		if mz, ok := mz.(piface.MessageV1); ok {
			parent = mz
		}
	}

	// Determine the v1 extension type, which is unfortunately not the same as
	// the v2 ExtensionType.GoType.
	extType := xt.GoType()
	switch extType.Kind() {
	case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
		extType = reflect.PtrTo(extType) // T -> *T for singular scalar fields
	case reflect.Ptr:
		if extType.Elem().Kind() == reflect.Slice {
			extType = extType.Elem() // *[]T -> []T for repeated fields
		}
	}

	// Reconstruct the legacy enum full name, which is an odd mixture of the
	// proto package name with the Go type name.
	var enumName string
	if xt.Descriptor().Kind() == pref.EnumKind {
		// Derive Go type name.
		t := extType
		if t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice {
			t = t.Elem()
		}
		enumName = t.Name()

		// Derive the proto package name.
		// For legacy enums, obtain the proto package from the raw descriptor.
		var protoPkg string
		if fd := xt.Descriptor().Enum().ParentFile(); fd != nil {
			protoPkg = string(fd.Package())
		}
		if ed, ok := reflect.Zero(t).Interface().(enumV1); ok && protoPkg == "" {
			b, _ := ed.EnumDescriptor()
			protoPkg = string(legacyLoadFileDesc(b).Package())
		}

		if protoPkg != "" {
			enumName = protoPkg + "." + enumName
		}
	}

	// Derive the proto file that the extension was declared within.
	var filename string
	if fd := xt.Descriptor().ParentFile(); fd != nil {
		filename = fd.Path()
	}

	// Construct and return a ExtensionDescV1.
	d := &piface.ExtensionDescV1{
		Type:          xt,
		ExtendedType:  parent,
		ExtensionType: reflect.Zero(extType).Interface(),
		Field:         int32(xt.Descriptor().Number()),
		Name:          string(xt.Descriptor().FullName()),
		Tag:           ptag.Marshal(xt.Descriptor(), enumName),
		Filename:      filename,
	}
	if d, ok := legacyExtensionDescCache.LoadOrStore(xt, d); ok {
		return d.(*piface.ExtensionDescV1)
	}
	return d
}

// legacyExtensionTypeFromDesc converts a protoiface.ExtensionDescV1 to a
// v2 protoreflect.ExtensionType. The returned descriptor type takes ownership
// of the input extension desc. The input must not be mutated so long as the
// returned type is still in use.
func legacyExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
	// Fast-path: check whether an extension type is already nested within.
	if d.Type != nil {
		return d.Type
	}

	// Fast-path: check the cache for whether this ExtensionType has already
	// been converted from a legacy descriptor.
	dk := legacyExtensionDescKeyOf(d)
	if t, ok := legacyExtensionTypeCache.Load(dk); ok {
		return t.(pref.ExtensionType)
	}

	// Resolve enum or message dependencies.
	var ed pref.EnumDescriptor
	var md pref.MessageDescriptor
	t := reflect.TypeOf(d.ExtensionType)
	isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
	isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
	if isOptional || isRepeated {
		t = t.Elem()
	}
	switch v := reflect.Zero(t).Interface().(type) {
	case pref.Enum:
		ed = v.Descriptor()
	case enumV1:
		ed = LegacyLoadEnumDesc(t)
	case pref.ProtoMessage:
		md = v.ProtoReflect().Descriptor()
	case messageV1:
		md = LegacyLoadMessageDesc(t)
	}

	// Derive basic field information from the struct tag.
	var evs pref.EnumValueDescriptors
	if ed != nil {
		evs = ed.Values()
	}
	fd := ptag.Unmarshal(d.Tag, t, evs).(*filedesc.Field)

	// Construct a v2 ExtensionType.
	xd := &filedesc.Extension{L2: new(filedesc.ExtensionL2)}
	xd.L0.ParentFile = filedesc.SurrogateProto2
	xd.L0.FullName = pref.FullName(d.Name)
	xd.L1.Number = pref.FieldNumber(d.Field)
	xd.L2.Cardinality = fd.L1.Cardinality
	xd.L1.Kind = fd.L1.Kind
	xd.L2.IsPacked = fd.L1.IsPacked
	xd.L2.Default = fd.L1.Default
	xd.L1.Extendee = Export{}.MessageDescriptorOf(d.ExtendedType)
	xd.L2.Enum = ed
	xd.L2.Message = md
	xt := LegacyExtensionTypeOf(xd, t)

	// Cache the conversion for both directions.
	legacyExtensionDescCache.LoadOrStore(xt, d)
	if xt, ok := legacyExtensionTypeCache.LoadOrStore(dk, xt); ok {
		return xt.(pref.ExtensionType)
	}
	return xt
}

// LegacyExtensionTypeOf returns a protoreflect.ExtensionType where the
// element type of the field is t. The type t must be provided if the field
// is an enum or message.
//
// This is exported for testing purposes.
func LegacyExtensionTypeOf(xd pref.ExtensionDescriptor, t reflect.Type) pref.ExtensionType {
	var conv pvalue.Converter
	var isLegacy bool
	xt := &prototype.Extension{ExtensionDescriptor: xd}
	switch xd.Kind() {
	case pref.EnumKind:
		conv, isLegacy = newConverter(t, xd.Kind())
		xt.NewEnum = conv.NewEnum
	case pref.MessageKind, pref.GroupKind:
		conv, isLegacy = newConverter(t, xd.Kind())
		xt.NewMessage = conv.NewMessage
	default:
		// Extension types for non-enums and non-messages are simple.
		return &prototype.Extension{ExtensionDescriptor: xd}
	}
	if !isLegacy {
		return xt
	}

	// Wrap ExtensionType such that GoType presents the legacy Go type.
	xt2 := &legacyExtensionType{ExtensionType: xt}
	if xd.Cardinality() != pref.Repeated {
		xt2.typ = t
		xt2.new = func() pref.Value {
			return xt.New()
		}
		xt2.valueOf = func(v interface{}) pref.Value {
			if reflect.TypeOf(v) != xt2.typ {
				panic(fmt.Sprintf("invalid type: got %T, want %v", v, xt2.typ))
			}
			if xd.Kind() == pref.EnumKind {
				return xt.ValueOf(Export{}.EnumOf(v))
			} else {
				return xt.ValueOf(Export{}.MessageOf(v).Interface())
			}
		}
		xt2.interfaceOf = func(v pref.Value) interface{} {
			return xt.InterfaceOf(v).(pvalue.Unwrapper).ProtoUnwrap()
		}
	} else {
		xt2.typ = reflect.PtrTo(reflect.SliceOf(t))
		xt2.new = func() pref.Value {
			v := reflect.New(xt2.typ.Elem()).Interface()
			return pref.ValueOf(pvalue.ListOf(v, conv))
		}
		xt2.valueOf = func(v interface{}) pref.Value {
			if reflect.TypeOf(v) != xt2.typ {
				panic(fmt.Sprintf("invalid type: got %T, want %v", v, xt2.typ))
			}
			return pref.ValueOf(pvalue.ListOf(v, conv))
		}
		xt2.interfaceOf = func(pv pref.Value) interface{} {
			v := pv.List().(pvalue.Unwrapper).ProtoUnwrap()
			if reflect.TypeOf(v) != xt2.typ {
				panic(fmt.Sprintf("invalid type: got %T, want %v", v, xt2.typ))
			}
			return v
		}
	}
	return xt2
}

type legacyExtensionType struct {
	pref.ExtensionType
	typ         reflect.Type
	new         func() pref.Value
	valueOf     func(interface{}) pref.Value
	interfaceOf func(pref.Value) interface{}
}

func (x *legacyExtensionType) GoType() reflect.Type                 { return x.typ }
func (x *legacyExtensionType) New() pref.Value                      { return x.new() }
func (x *legacyExtensionType) ValueOf(v interface{}) pref.Value     { return x.valueOf(v) }
func (x *legacyExtensionType) InterfaceOf(v pref.Value) interface{} { return x.interfaceOf(v) }
func (x *legacyExtensionType) Format(s fmt.State, r rune)           { descfmt.FormatDesc(s, r, x.Descriptor()) }
