// 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 LICEqNSE file.

package impl

import (
	"fmt"
	"reflect"
	"strings"
	"sync"

	"google.golang.org/protobuf/internal/filedesc"
	"google.golang.org/protobuf/internal/strs"
	"google.golang.org/protobuf/reflect/protoreflect"
	pref "google.golang.org/protobuf/reflect/protoreflect"
)

// legacyEnumName returns the name of enums used in legacy code.
// It is neither the protobuf full name nor the qualified Go name,
// but rather an odd hybrid of both.
func legacyEnumName(ed pref.EnumDescriptor) string {
	var protoPkg string
	enumName := string(ed.FullName())
	if fd := ed.ParentFile(); fd != nil {
		protoPkg = string(fd.Package())
		enumName = strings.TrimPrefix(enumName, protoPkg+".")
	}
	if protoPkg == "" {
		return strs.GoCamelCase(enumName)
	}
	return protoPkg + "." + strs.GoCamelCase(enumName)
}

// legacyWrapEnum wraps v as a protoreflect.Enum,
// where v must be a int32 kind and not implement the v2 API already.
func legacyWrapEnum(v reflect.Value) pref.Enum {
	et := legacyLoadEnumType(v.Type())
	return et.New(pref.EnumNumber(v.Int()))
}

var legacyEnumTypeCache sync.Map // map[reflect.Type]protoreflect.EnumType

// legacyLoadEnumType dynamically loads a protoreflect.EnumType for t,
// where t must be an int32 kind and not implement the v2 API already.
func legacyLoadEnumType(t reflect.Type) pref.EnumType {
	// Fast-path: check if a EnumType is cached for this concrete type.
	if et, ok := legacyEnumTypeCache.Load(t); ok {
		return et.(pref.EnumType)
	}

	// Slow-path: derive enum descriptor and initialize EnumType.
	var et pref.EnumType
	ed := LegacyLoadEnumDesc(t)
	et = &legacyEnumType{
		desc:   ed,
		goType: t,
	}
	if et, ok := legacyEnumTypeCache.LoadOrStore(t, et); ok {
		return et.(pref.EnumType)
	}
	return et
}

type legacyEnumType struct {
	desc   pref.EnumDescriptor
	goType reflect.Type
	m      sync.Map // map[protoreflect.EnumNumber]proto.Enum
}

func (t *legacyEnumType) New(n pref.EnumNumber) pref.Enum {
	if e, ok := t.m.Load(n); ok {
		return e.(pref.Enum)
	}
	e := &legacyEnumWrapper{num: n, pbTyp: t, goTyp: t.goType}
	t.m.Store(n, e)
	return e
}
func (t *legacyEnumType) Descriptor() pref.EnumDescriptor {
	return t.desc
}

type legacyEnumWrapper struct {
	num   pref.EnumNumber
	pbTyp pref.EnumType
	goTyp reflect.Type
}

func (e *legacyEnumWrapper) Descriptor() pref.EnumDescriptor {
	return e.pbTyp.Descriptor()
}
func (e *legacyEnumWrapper) Type() pref.EnumType {
	return e.pbTyp
}
func (e *legacyEnumWrapper) Number() pref.EnumNumber {
	return e.num
}
func (e *legacyEnumWrapper) ProtoReflect() pref.Enum {
	return e
}
func (e *legacyEnumWrapper) protoUnwrap() interface{} {
	v := reflect.New(e.goTyp).Elem()
	v.SetInt(int64(e.num))
	return v.Interface()
}

var (
	_ pref.Enum = (*legacyEnumWrapper)(nil)
	_ unwrapper = (*legacyEnumWrapper)(nil)
)

var legacyEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor

// LegacyLoadEnumDesc returns an EnumDescriptor derived from the Go type,
// which must be an int32 kind and not implement the v2 API already.
//
// This is exported for testing purposes.
func LegacyLoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
	// Fast-path: check if an EnumDescriptor is cached for this concrete type.
	if ed, ok := legacyEnumDescCache.Load(t); ok {
		return ed.(pref.EnumDescriptor)
	}

	// Slow-path: initialize EnumDescriptor from the raw descriptor.
	ev := reflect.Zero(t).Interface()
	if _, ok := ev.(pref.Enum); ok {
		panic(fmt.Sprintf("%v already implements proto.Enum", t))
	}
	edV1, ok := ev.(enumV1)
	if !ok {
		return aberrantLoadEnumDesc(t)
	}
	b, idxs := edV1.EnumDescriptor()

	var ed pref.EnumDescriptor
	if len(idxs) == 1 {
		ed = legacyLoadFileDesc(b).Enums().Get(idxs[0])
	} else {
		md := legacyLoadFileDesc(b).Messages().Get(idxs[0])
		for _, i := range idxs[1 : len(idxs)-1] {
			md = md.Messages().Get(i)
		}
		ed = md.Enums().Get(idxs[len(idxs)-1])
	}
	if ed, ok := legacyEnumDescCache.LoadOrStore(t, ed); ok {
		return ed.(protoreflect.EnumDescriptor)
	}
	return ed
}

var aberrantEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor

// aberrantLoadEnumDesc returns an EnumDescriptor derived from the Go type,
// which must not implement protoreflect.Enum or enumV1.
//
// If the type does not implement enumV1, then there is no reliable
// way to derive the original protobuf type information.
// We are unable to use the global enum registry since it is
// unfortunately keyed by the protobuf full name, which we also do not know.
// Thus, this produces some bogus enum descriptor based on the Go type name.
func aberrantLoadEnumDesc(t reflect.Type) pref.EnumDescriptor {
	// Fast-path: check if an EnumDescriptor is cached for this concrete type.
	if ed, ok := aberrantEnumDescCache.Load(t); ok {
		return ed.(pref.EnumDescriptor)
	}

	// Slow-path: construct a bogus, but unique EnumDescriptor.
	ed := &filedesc.Enum{L2: new(filedesc.EnumL2)}
	ed.L0.FullName = AberrantDeriveFullName(t) // e.g., github_com.user.repo.MyEnum
	ed.L0.ParentFile = filedesc.SurrogateProto3
	ed.L2.Values.List = append(ed.L2.Values.List, filedesc.EnumValue{})

	// TODO: Use the presence of a UnmarshalJSON method to determine proto2?

	vd := &ed.L2.Values.List[0]
	vd.L0.FullName = ed.L0.FullName + "_UNKNOWN" // e.g., github_com.user.repo.MyEnum_UNKNOWN
	vd.L0.ParentFile = ed.L0.ParentFile
	vd.L0.Parent = ed

	// TODO: We could use the String method to obtain some enum value names by
	// starting at 0 and print the enum until it produces invalid identifiers.
	// An exhaustive query is clearly impractical, but can be best-effort.

	if ed, ok := aberrantEnumDescCache.LoadOrStore(t, ed); ok {
		return ed.(pref.EnumDescriptor)
	}
	return ed
}

// AberrantDeriveFullName derives a fully qualified protobuf name for the given Go type
// The provided name is not guaranteed to be stable nor universally unique.
// It should be sufficiently unique within a program.
//
// This is exported for testing purposes.
func AberrantDeriveFullName(t reflect.Type) pref.FullName {
	sanitize := func(r rune) rune {
		switch {
		case r == '/':
			return '.'
		case 'a' <= r && r <= 'z', 'A' <= r && r <= 'Z', '0' <= r && r <= '9':
			return r
		default:
			return '_'
		}
	}
	prefix := strings.Map(sanitize, t.PkgPath())
	suffix := strings.Map(sanitize, t.Name())
	if suffix == "" {
		suffix = fmt.Sprintf("UnknownX%X", reflect.ValueOf(t).Pointer())
	}

	ss := append(strings.Split(prefix, "."), suffix)
	for i, s := range ss {
		if s == "" || ('0' <= s[0] && s[0] <= '9') {
			ss[i] = "x" + s
		}
	}
	return pref.FullName(strings.Join(ss, "."))
}
