// Copyright 2020 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 protobuild constructs messages.
//
// This package is used to construct multiple types of message with a similar shape
// from a common template.
package protobuild

import (
	"fmt"
	"math"
	"reflect"

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

// A Value is a value assignable to a field.
// A Value may be a value accepted by protoreflect.ValueOf. In addition:
//
// • An int may be assigned to any numeric field.
//
// • A float64 may be assigned to a double field.
//
// • Either a string or []byte may be assigned to a string or bytes field.
//
// • A string containing the value name may be assigned to an enum field.
//
// • A slice may be assigned to a list, and a map may be assigned to a map.
type Value interface{}

// A Message is a template to apply to a message. Keys are field names, including
// extension names.
type Message map[pref.Name]Value

// Unknown is a key associated with the unknown fields of a message.
// The value should be a []byte.
const Unknown = "@unknown"

// Build applies the template to a message.
func (template Message) Build(m pref.Message) {
	md := m.Descriptor()
	fields := md.Fields()
	exts := make(map[pref.Name]pref.FieldDescriptor)
	protoregistry.GlobalTypes.RangeExtensionsByMessage(md.FullName(), func(xt pref.ExtensionType) bool {
		xd := xt.TypeDescriptor()
		exts[xd.Name()] = xd
		return true
	})
	for k, v := range template {
		if k == Unknown {
			m.SetUnknown(pref.RawFields(v.([]byte)))
			continue
		}
		fd := fields.ByName(k)
		if fd == nil {
			fd = exts[k]
		}
		if fd == nil {
			panic(fmt.Sprintf("%v.%v: not found", md.FullName(), k))
		}
		switch {
		case fd.IsList():
			list := m.Mutable(fd).List()
			s := reflect.ValueOf(v)
			for i := 0; i < s.Len(); i++ {
				if fd.Message() == nil {
					list.Append(fieldValue(fd, s.Index(i).Interface()))
				} else {
					e := list.NewElement()
					s.Index(i).Interface().(Message).Build(e.Message())
					list.Append(e)
				}
			}
		case fd.IsMap():
			mapv := m.Mutable(fd).Map()
			rm := reflect.ValueOf(v)
			for _, k := range rm.MapKeys() {
				mk := fieldValue(fd.MapKey(), k.Interface()).MapKey()
				if fd.MapValue().Message() == nil {
					mv := fieldValue(fd.MapValue(), rm.MapIndex(k).Interface())
					mapv.Set(mk, mv)
				} else if mapv.Has(mk) {
					mv := mapv.Get(mk).Message()
					rm.MapIndex(k).Interface().(Message).Build(mv)
				} else {
					mv := mapv.NewValue()
					rm.MapIndex(k).Interface().(Message).Build(mv.Message())
					mapv.Set(mk, mv)
				}
			}
		default:
			if fd.Message() == nil {
				m.Set(fd, fieldValue(fd, v))
			} else {
				v.(Message).Build(m.Mutable(fd).Message())
			}
		}

	}
}

func fieldValue(fd pref.FieldDescriptor, v interface{}) pref.Value {
	switch o := v.(type) {
	case int:
		switch fd.Kind() {
		case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
			if min, max := math.MinInt32, math.MaxInt32; o < min || o > max {
				panic(fmt.Sprintf("%v: value %v out of range [%v, %v]", fd.FullName(), o, min, max))
			}
			v = int32(o)
		case pref.Uint32Kind, pref.Fixed32Kind:
			if min, max := 0, math.MaxUint32; o < min || o > max {
				panic(fmt.Sprintf("%v: value %v out of range [%v, %v]", fd.FullName(), o, min, max))
			}
			v = uint32(o)
		case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
			v = int64(o)
		case pref.Uint64Kind, pref.Fixed64Kind:
			if o < 0 {
				panic(fmt.Sprintf("%v: value %v out of range [%v, %v]", fd.FullName(), o, 0, uint64(math.MaxUint64)))
			}
			v = uint64(o)
		case pref.FloatKind:
			v = float32(o)
		case pref.DoubleKind:
			v = float64(o)
		case pref.EnumKind:
			v = pref.EnumNumber(o)
		default:
			panic(fmt.Sprintf("%v: invalid value type int", fd.FullName()))
		}
	case float64:
		switch fd.Kind() {
		case pref.FloatKind:
			v = float32(o)
		}
	case string:
		switch fd.Kind() {
		case pref.BytesKind:
			v = []byte(o)
		case pref.EnumKind:
			v = fd.Enum().Values().ByName(pref.Name(o)).Number()
		}
	case []byte:
		return pref.ValueOf(append([]byte{}, o...))
	}
	return pref.ValueOf(v)
}
