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

import (
	"fmt"
	"math"
	"os"
	"reflect"
	"strconv"
	"strings"

	"github.com/golang/protobuf/v2/protogen"
	"github.com/golang/protobuf/v2/reflect/protoreflect"
)

// TODO: Remove this flag.
// Remember to remove the copy in internal/protogen/goldentest.
var enableReflectFlag = os.Getenv("PROTOC_GEN_GO_ENABLE_REFLECT") != ""

func enableReflection(f *protogen.File) bool {
	return enableReflectFlag || isDescriptor(f)
}

// TODO: Remove special-casing for descriptor proto.
func isDescriptor(f *protogen.File) bool {
	return f.Desc.Path() == "google/protobuf/descriptor.proto" && f.Desc.Package() == "google.protobuf"
}

// minimumVersion is minimum version of the v2 proto package that is required.
// This is incremented every time the generated code relies on some property
// in the proto package that was introduced in a later version.
const minimumVersion = 0

const (
	protoimplPackage    = protogen.GoImportPath("github.com/golang/protobuf/v2/runtime/protoimpl")
	protoreflectPackage = protogen.GoImportPath("github.com/golang/protobuf/v2/reflect/protoreflect")
	prototypePackage    = protogen.GoImportPath("github.com/golang/protobuf/v2/reflect/prototype")
)

// TODO: Add support for proto options.

func genReflectInitFunction(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo) {
	if !enableReflection(f.File) {
		return
	}

	if len(f.allEnums)+len(f.allMessages)+len(f.allExtensions)+len(f.Services) == 0 {
		return
	}

	g.P("func init() {")

	// TODO: Fix up file imports to reference a protoreflect.FileDescriptor
	// in a remote dependency. Since we cannot yet rely on the existence of
	// a variable containing the file descriptor, we find a random message or
	// enum the package and see if we can ascend to the parent file descriptor.

	fileDescVar := fileDescVarName(f)
	enumTypesVar := enumTypesVarName(f)
	enumDescsVar := enumDescsVarName(f)
	messageTypesVar := messageTypesVarName(f)
	messageDescsVar := messageDescsVarName(f)

	// Populate all declarations for messages and enums.
	// These are not declared in the literals to avoid an initialization loop.
	if enums := f.Enums; len(enums) > 0 {
		i := f.allEnumsByPtr[enums[0]]
		g.P(fileDescVar, ".Enums = ", enumDescsVar, "[", i, ":", i+len(enums), "]")
	}
	if messages := f.Messages; len(messages) > 0 {
		i := f.allMessagesByPtr[messages[0]]
		g.P(fileDescVar, ".Messages = ", messageDescsVar, "[", i, ":", i+len(messages), "]")
	}
	for i, message := range f.allMessages {
		if enums := message.Enums; len(enums) > 0 {
			j := f.allEnumsByPtr[enums[0]]
			g.P(messageDescsVar, "[", i, "].Enums = ", enumDescsVar, "[", j, ":", j+len(enums), "]")
		}
		if messages := message.Messages; len(messages) > 0 {
			j := f.allMessagesByPtr[messages[0]]
			g.P(messageDescsVar, "[", i, "].Messages = ", messageDescsVar, "[", j, ":", j+len(messages), "]")
		}
	}

	// Populate all dependencies for messages and enums.
	//
	// Externally defined enums and messages may or may not support the
	// v2 protobuf reflection interfaces. The EnumTypeOf and MessageTypeOf
	// helper functions checks for compliance and derives a v2 type from the
	// legacy v1 enum or message if necessary.
	for i, message := range f.allMessages {
		for j, field := range message.Fields {
			fieldSel := fmt.Sprintf("[%d].Fields[%d]", i, j)
			if et := field.EnumType; et != nil {
				idx, ok := f.allEnumsByPtr[et]
				if ok {
					// Locally defined enums are found in the type array.
					g.P(messageDescsVar, fieldSel, ".EnumType = ", enumTypesVar, "[", idx, "]")
				} else {
					// Externally defined enums may need special handling.
					g.P(messageDescsVar, fieldSel, ".EnumType = ", protoimplPackage.Ident("X"), ".EnumTypeOf(", et.GoIdent, "(0))")
				}
			}
			if mt := field.MessageType; mt != nil {
				idx, ok := f.allMessagesByPtr[mt]
				if ok {
					if mt.Desc.IsMapEntry() {
						// Map entry types have no Go type generated for them.
						g.P(messageDescsVar, fieldSel, ".MessageType = ", messageDescsVar, "[", idx, "].Reference()")
					} else {
						// Locally defined messages are found in the type array.
						g.P(messageDescsVar, fieldSel, ".MessageType = ", messageTypesVar, "[", idx, "].Type")
					}
				} else {
					// Externally defined messages may need special handling.
					g.P(messageDescsVar, fieldSel, ".MessageType = ", protoimplPackage.Ident("X"), ".MessageTypeOf((*", mt.GoIdent, ")(nil))")
				}
			}
		}
	}
	// TODO: Fix up extension dependencies.
	// TODO: Fix up method dependencies.

	// Construct the file descriptor.
	g.P("var err error")
	g.P(f.GoDescriptorIdent, ", err = ", prototypePackage.Ident("NewFile"), "(&", fileDescVarName(f), ")")
	g.P("if err != nil { panic(err) }")

	// TODO: Add v2 registration and stop v1 registration in genInitFunction.

	// The descriptor proto needs to register the option types with the
	// prototype so that the package can properly handle those option types.
	if isDescriptor(f.File) {
		for _, m := range f.allMessages {
			name := m.GoIdent.GoName
			if strings.HasSuffix(name, "Options") {
				g.P(prototypePackage.Ident("X"), ".Register", name, "((*", name, ")(nil))")
			}
		}
	}

	g.P("}")
}

func genReflectFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo) {
	if !enableReflection(f.File) {
		return
	}

	// Emit a static check that enforces a minimum version of the proto package.
	g.P("const _ = ", protoimplPackage.Ident("EnforceVersion"), "(", protoimplPackage.Ident("Version"), " - ", minimumVersion, ")")

	g.P("var ", f.GoDescriptorIdent, " ", protoreflectPackage.Ident("FileDescriptor"))
	g.P()

	// Generate literal for file descriptor.
	fileDescVar := fileDescVarName(f)
	g.P("var ", fileDescVar, " = ", prototypePackage.Ident("File"), "{")
	g.P("Syntax: ", protoreflectPackage.Ident(f.Desc.Syntax().GoString()), ",")
	g.P("Path: ", strconv.Quote(f.Desc.Path()), ",")
	g.P("Package: ", strconv.Quote(string(f.Desc.Package())), ",")
	if imps := f.Desc.Imports(); imps.Len() > 0 {
		g.P("Imports: ", "[]", protoreflectPackage.Ident("FileImport"), "{")
		for i := 0; i < imps.Len(); i++ {
			imp := imps.Get(i)
			path := strconv.Quote(imp.Path())
			pkg := strconv.Quote(string(imp.Package()))
			var isPublic, isWeak string
			if imp.IsPublic {
				isPublic = ", IsPublic: true"
			}
			if imp.IsWeak {
				isWeak = ", IsWeak: true"
			}
			// NOTE: FileDescriptor may be updated later by init.
			g.P("{FileDescriptor: ", prototypePackage.Ident("PlaceholderFile"), "(", path, ", ", pkg, ")", isPublic, isWeak, "},")
		}
		g.P("},")
	}
	// NOTE: Messages, Enums, Extensions, and Services are populated by init.
	g.P("}")

	// Generate literals for enum descriptors.
	if len(f.allEnums) > 0 {
		enumTypesVar := enumTypesVarName(f)
		enumDescsVar := enumDescsVarName(f)
		g.P("var ", enumTypesVar, " = [", len(f.allEnums), "]", protoreflectPackage.Ident("EnumType"), "{")
		for i, enum := range f.allEnums {
			g.P(prototypePackage.Ident("GoEnum"), "(")
			g.P(enumDescsVar, "[", i, "].Reference(),")
			g.P("func(_ ", protoreflectPackage.Ident("EnumType"), ", n ", protoreflectPackage.Ident("EnumNumber"), ") ", protoreflectPackage.Ident("ProtoEnum"), " {")
			g.P("return ", enum.GoIdent, "(n)")
			g.P("},")
			g.P("),")
		}
		g.P("}")

		g.P("var ", enumDescsVar, " = [", len(f.allEnums), "]", prototypePackage.Ident("Enum"), "{")
		for _, enum := range f.allEnums {
			g.P("{")
			g.P("Name: ", strconv.Quote(string(enum.Desc.Name())), ",")
			g.P("Values: []", prototypePackage.Ident("EnumValue"), "{")
			for _, value := range enum.Values {
				g.P("{Name: ", strconv.Quote(string(value.Desc.Name())), ", Number: ", value.Desc.Number(), "},")
			}
			g.P("},")
			g.P("},")
		}
		g.P("}")
	}

	// Generate literals for message descriptors.
	if len(f.allMessages) > 0 {
		messageTypesVar := messageTypesVarName(f)
		messageDescsVar := messageDescsVarName(f)
		g.P("var ", messageTypesVar, " = [", len(f.allMessages), "]", protoimplPackage.Ident("MessageType"), "{")
		for i, message := range f.allMessages {
			if message.Desc.IsMapEntry() {
				// Map entry types have no Go type generated for them.
				g.P("{ /* no message type for ", message.GoIdent, " */ },")
				continue
			}
			g.P("{Type: ", prototypePackage.Ident("GoMessage"), "(")
			g.P(messageDescsVar, "[", i, "].Reference(),")
			g.P("func(", protoreflectPackage.Ident("MessageType"), ") ", protoreflectPackage.Ident("ProtoMessage"), " {")
			g.P("return new(", message.GoIdent, ")")
			g.P("},")
			g.P(")},")
		}
		g.P("}")

		g.P("var ", messageDescsVar, " = [", len(f.allMessages), "]", prototypePackage.Ident("Message"), "{")
		for _, message := range f.allMessages {
			g.P("{")
			g.P("Name: ", strconv.Quote(string(message.Desc.Name())), ",")
			if fields := message.Desc.Fields(); fields.Len() > 0 {
				g.P("Fields: []", prototypePackage.Ident("Field"), "{")
				for i := 0; i < fields.Len(); i++ {
					field := fields.Get(i)
					g.P("{")
					g.P("Name: ", strconv.Quote(string(field.Name())), ",")
					g.P("Number: ", field.Number(), ",")
					g.P("Cardinality: ", protoreflectPackage.Ident(field.Cardinality().GoString()), ",")
					g.P("Kind: ", protoreflectPackage.Ident(field.Kind().GoString()), ",")
					// TODO: omit JSONName if it can be derived from Name?
					g.P("JSONName: ", strconv.Quote(field.JSONName()), ",")
					if field.HasDefault() {
						v := field.Default().Interface()
						typeName := reflect.TypeOf(v).Name()
						valLit := fmt.Sprint(v)
						switch v.(type) {
						case protoreflect.EnumNumber:
							typeName = "string"
							valLit = strconv.Quote(string(field.DefaultEnumValue().Name()))
						case float32, float64:
							switch f := field.Default().Float(); {
							case math.IsInf(f, -1):
								valLit = g.QualifiedGoIdent(mathPackage.Ident("Inf")) + "(-1)"
							case math.IsInf(f, +1):
								valLit = g.QualifiedGoIdent(mathPackage.Ident("Inf")) + "(+1)"
							case math.IsNaN(f):
								valLit = g.QualifiedGoIdent(mathPackage.Ident("NaN")) + "()"
							}
						case string, []byte:
							valLit = fmt.Sprintf("%q", v)
						}
						g.P("Default: ", protoreflectPackage.Ident("ValueOf"), "(", typeName, "(", valLit, ")),")
					}
					if oneof := field.OneofType(); oneof != nil {
						g.P("OneofName: ", strconv.Quote(string(oneof.Name())), ",")
					}
					// NOTE: MessageType and EnumType are populated by init.
					g.P("},")
				}
				g.P("},")
			}
			if oneofs := message.Desc.Oneofs(); oneofs.Len() > 0 {
				g.P("Oneofs: []", prototypePackage.Ident("Oneof"), "{")
				for i := 0; i < oneofs.Len(); i++ {
					oneof := oneofs.Get(i)
					g.P("{Name: ", strconv.Quote(string(oneof.Name())), "},")
				}
				g.P("},")
			}
			if extRanges := message.Desc.ExtensionRanges(); extRanges.Len() > 0 {
				var ss []string
				for i := 0; i < extRanges.Len(); i++ {
					r := extRanges.Get(i)
					ss = append(ss, fmt.Sprintf("{%d,%d}", r[0], r[1]))
				}
				g.P("ExtensionRanges: [][2]", protoreflectPackage.Ident("FieldNumber"), "{", strings.Join(ss, ","), "},")
			}
			// NOTE: Messages, Enums, and Extensions are populated by init.
			g.P("},")
		}
		g.P("}")
	}

	// TODO: Add support for extensions.
	// TODO: Add support for services.
}

func genReflectEnum(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, enum *protogen.Enum) {
	if !enableReflection(f.File) {
		return
	}

	shadowType := shadowTypeName(enum.GoIdent)
	g.P("type ", shadowType, " ", enum.GoIdent)
	g.P()

	idx := f.allEnumsByPtr[enum]
	typesVar := enumTypesVarName(f)
	g.P("func (e ", enum.GoIdent, ") ProtoReflect() ", protoreflectPackage.Ident("Enum"), " {")
	g.P("return (", shadowType, ")(e)")
	g.P("}")
	g.P("func (e ", shadowType, ") Type() ", protoreflectPackage.Ident("EnumType"), " {")
	g.P("return ", typesVar, "[", idx, "]")
	g.P("}")
	g.P("func (e ", shadowType, ") Number() ", protoreflectPackage.Ident("EnumNumber"), " {")
	g.P("return ", protoreflectPackage.Ident("EnumNumber"), "(e)")
	g.P("}")
}

func genReflectMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, message *protogen.Message) {
	if !enableReflection(f.File) {
		return
	}

	shadowType := shadowTypeName(message.GoIdent)
	g.P("type ", shadowType, " struct{m *", message.GoIdent, "}")
	g.P()

	idx := f.allMessagesByPtr[message]
	typesVar := messageTypesVarName(f)
	g.P("func (m *", message.GoIdent, ") ProtoReflect() ", protoreflectPackage.Ident("Message"), " {")
	g.P("return ", shadowType, "{m}")
	g.P("}")
	g.P("func (m ", shadowType, ") Type() ", protoreflectPackage.Ident("MessageType"), " {")
	g.P("return ", typesVar, "[", idx, "].Type")
	g.P("}")
	g.P("func (m ", shadowType, ") KnownFields() ", protoreflectPackage.Ident("KnownFields"), " {")
	g.P("return ", typesVar, "[", idx, "].KnownFieldsOf(m.m)")
	g.P("}")
	g.P("func (m ", shadowType, ") UnknownFields() ", protoreflectPackage.Ident("UnknownFields"), " {")
	g.P("return ", typesVar, "[", idx, "].UnknownFieldsOf(m.m)")
	g.P("}")
	g.P("func (m ", shadowType, ") Interface() ", protoreflectPackage.Ident("ProtoMessage"), " {")
	g.P("return m.m")
	g.P("}")
	g.P("func (m ", shadowType, ") ProtoMutable() {}")
	g.P()
}

func fileDescVarName(f *fileInfo) string {
	return "xxx_" + f.GoDescriptorIdent.GoName + "_FileDesc"
}
func enumTypesVarName(f *fileInfo) string {
	return "xxx_" + f.GoDescriptorIdent.GoName + "_EnumTypes"
}
func enumDescsVarName(f *fileInfo) string {
	return "xxx_" + f.GoDescriptorIdent.GoName + "_EnumDescs"
}
func messageTypesVarName(f *fileInfo) string {
	return "xxx_" + f.GoDescriptorIdent.GoName + "_MessageTypes"
}
func messageDescsVarName(f *fileInfo) string {
	return "xxx_" + f.GoDescriptorIdent.GoName + "_MessageDescs"
}
func extensionDescsVarName(f *fileInfo) string {
	return "xxx_" + f.GoDescriptorIdent.GoName + "_ExtensionDescs"
}
func shadowTypeName(ident protogen.GoIdent) string {
	return "xxx_" + ident.GoName
}
