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

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

// Unwrapper unwraps the value to the underlying value.
// This is implemented by List and Map.
type Unwrapper interface {
	ProtoUnwrap() interface{}
}

// A Converter coverts to/from Go reflect.Value types and protobuf protoreflect.Value types.
type Converter interface {
	// PBValueOf converts a reflect.Value to a protoreflect.Value.
	PBValueOf(reflect.Value) pref.Value

	// GoValueOf converts a protoreflect.Value to a reflect.Value.
	GoValueOf(pref.Value) reflect.Value

	// New returns a new field value.
	// For scalars, it returns the default value of the field.
	// For composite types, it returns a new mutable value.
	New() pref.Value

	// Zero returns a new field value.
	// For scalars, it returns the default value of the field.
	// For composite types, it returns an immutable, empty value.
	Zero() pref.Value
}

// NewConverter matches a Go type with a protobuf field and returns a Converter
// that converts between the two. Enums must be a named int32 kind that
// implements protoreflect.Enum, and messages must be pointer to a named
// struct type that implements protoreflect.ProtoMessage.
//
// This matcher deliberately supports a wider range of Go types than what
// protoc-gen-go historically generated to be able to automatically wrap some
// v1 messages generated by other forks of protoc-gen-go.
func NewConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
	switch {
	case fd.IsList():
		return newListConverter(t, fd)
	case fd.IsMap():
		return newMapConverter(t, fd)
	default:
		return newSingularConverter(t, fd)
	}
	panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
}

var (
	boolType    = reflect.TypeOf(bool(false))
	int32Type   = reflect.TypeOf(int32(0))
	int64Type   = reflect.TypeOf(int64(0))
	uint32Type  = reflect.TypeOf(uint32(0))
	uint64Type  = reflect.TypeOf(uint64(0))
	float32Type = reflect.TypeOf(float32(0))
	float64Type = reflect.TypeOf(float64(0))
	stringType  = reflect.TypeOf(string(""))
	bytesType   = reflect.TypeOf([]byte(nil))
	byteType    = reflect.TypeOf(byte(0))
)

var (
	boolZero    = pref.ValueOf(bool(false))
	int32Zero   = pref.ValueOf(int32(0))
	int64Zero   = pref.ValueOf(int64(0))
	uint32Zero  = pref.ValueOf(uint32(0))
	uint64Zero  = pref.ValueOf(uint64(0))
	float32Zero = pref.ValueOf(float32(0))
	float64Zero = pref.ValueOf(float64(0))
	stringZero  = pref.ValueOf(string(""))
	bytesZero   = pref.ValueOf([]byte(nil))
)

type scalarConverter struct {
	goType, pbType reflect.Type
	def            pref.Value
}

func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
	defVal := func(fd pref.FieldDescriptor, zero pref.Value) pref.Value {
		if fd.Cardinality() == pref.Repeated {
			// Default isn't defined for repeated fields.
			return zero
		}
		return fd.Default()
	}
	switch fd.Kind() {
	case pref.BoolKind:
		if t.Kind() == reflect.Bool {
			return &scalarConverter{t, boolType, defVal(fd, boolZero)}
		}
	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
		if t.Kind() == reflect.Int32 {
			return &scalarConverter{t, int32Type, defVal(fd, int32Zero)}
		}
	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
		if t.Kind() == reflect.Int64 {
			return &scalarConverter{t, int64Type, defVal(fd, int64Zero)}
		}
	case pref.Uint32Kind, pref.Fixed32Kind:
		if t.Kind() == reflect.Uint32 {
			return &scalarConverter{t, uint32Type, defVal(fd, uint32Zero)}
		}
	case pref.Uint64Kind, pref.Fixed64Kind:
		if t.Kind() == reflect.Uint64 {
			return &scalarConverter{t, uint64Type, defVal(fd, uint64Zero)}
		}
	case pref.FloatKind:
		if t.Kind() == reflect.Float32 {
			return &scalarConverter{t, float32Type, defVal(fd, float32Zero)}
		}
	case pref.DoubleKind:
		if t.Kind() == reflect.Float64 {
			return &scalarConverter{t, float64Type, defVal(fd, float64Zero)}
		}
	case pref.StringKind:
		if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
			return &scalarConverter{t, stringType, defVal(fd, stringZero)}
		}
	case pref.BytesKind:
		if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
			return &scalarConverter{t, bytesType, defVal(fd, bytesZero)}
		}
	case pref.EnumKind:
		// Handle enums, which must be a named int32 type.
		if t.Kind() == reflect.Int32 {
			return newEnumConverter(t, fd)
		}
	case pref.MessageKind, pref.GroupKind:
		return newMessageConverter(t)
	}
	panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
}

func (c *scalarConverter) PBValueOf(v reflect.Value) pref.Value {
	if v.Type() != c.goType {
		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
	}
	if c.goType.Kind() == reflect.String && c.pbType.Kind() == reflect.Slice && v.Len() == 0 {
		return pref.ValueOf([]byte(nil)) // ensure empty string is []byte(nil)
	}
	return pref.ValueOf(v.Convert(c.pbType).Interface())
}

func (c *scalarConverter) GoValueOf(v pref.Value) reflect.Value {
	rv := reflect.ValueOf(v.Interface())
	if rv.Type() != c.pbType {
		panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.pbType))
	}
	if c.pbType.Kind() == reflect.String && c.goType.Kind() == reflect.Slice && rv.Len() == 0 {
		return reflect.Zero(c.goType) // ensure empty string is []byte(nil)
	}
	return rv.Convert(c.goType)
}

func (c *scalarConverter) New() pref.Value {
	if c.pbType == bytesType {
		return pref.ValueOf(append(([]byte)(nil), c.def.Bytes()...))
	}
	return c.def
}

func (c *scalarConverter) Zero() pref.Value {
	return c.New()
}

type enumConverter struct {
	goType reflect.Type
	def    pref.Value
}

func newEnumConverter(goType reflect.Type, fd pref.FieldDescriptor) Converter {
	var def pref.Value
	if fd.Cardinality() == pref.Repeated {
		def = pref.ValueOf(fd.Enum().Values().Get(0).Number())
	} else {
		def = fd.Default()
	}
	return &enumConverter{goType, def}
}

func (c *enumConverter) PBValueOf(v reflect.Value) pref.Value {
	if v.Type() != c.goType {
		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
	}
	return pref.ValueOf(pref.EnumNumber(v.Int()))
}

func (c *enumConverter) GoValueOf(v pref.Value) reflect.Value {
	return reflect.ValueOf(v.Enum()).Convert(c.goType)
}

func (c *enumConverter) New() pref.Value {
	return c.def
}

func (c *enumConverter) Zero() pref.Value {
	return c.def
}

type messageConverter struct {
	goType reflect.Type
}

func newMessageConverter(goType reflect.Type) Converter {
	return &messageConverter{goType}
}

func (c *messageConverter) PBValueOf(v reflect.Value) pref.Value {
	if v.Type() != c.goType {
		panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
	}
	if m, ok := v.Interface().(pref.ProtoMessage); ok {
		return pref.ValueOf(m.ProtoReflect())
	}
	return pref.ValueOf(legacyWrapMessage(v).ProtoReflect())
}

func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value {
	m := v.Message()
	var rv reflect.Value
	if u, ok := m.(Unwrapper); ok {
		rv = reflect.ValueOf(u.ProtoUnwrap())
	} else {
		rv = reflect.ValueOf(m.Interface())
	}
	if rv.Type() != c.goType {
		panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.goType))
	}
	return rv
}

func (c *messageConverter) New() pref.Value {
	return c.PBValueOf(reflect.New(c.goType.Elem()))
}

func (c *messageConverter) Zero() pref.Value {
	return c.PBValueOf(reflect.Zero(c.goType))
}
