// Copyright 2015 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 jsonpb

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"math"
	"reflect"
	"strconv"
	"strings"
	"time"

	"github.com/golang/protobuf/proto"
	"google.golang.org/protobuf/encoding/protojson"
	protoV2 "google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"
)

const wrapJSONUnmarshalV2 = false

// UnmarshalNext unmarshals the next JSON object from d into m.
func UnmarshalNext(d *json.Decoder, m proto.Message) error {
	return new(Unmarshaler).UnmarshalNext(d, m)
}

// Unmarshal unmarshals a JSON object from r into m.
func Unmarshal(r io.Reader, m proto.Message) error {
	return new(Unmarshaler).Unmarshal(r, m)
}

// UnmarshalString unmarshals a JSON object from s into m.
func UnmarshalString(s string, m proto.Message) error {
	return new(Unmarshaler).Unmarshal(strings.NewReader(s), m)
}

// Unmarshaler is a configurable object for converting from a JSON
// representation to a protocol buffer object.
type Unmarshaler struct {
	// AllowUnknownFields specifies whether to allow messages to contain
	// unknown JSON fields, as opposed to failing to unmarshal.
	AllowUnknownFields bool

	// AnyResolver is used to resolve the google.protobuf.Any well-known type.
	// If unset, the global registry is used by default.
	AnyResolver AnyResolver
}

// JSONPBUnmarshaler is implemented by protobuf messages that customize the way
// they are unmarshaled from JSON. Messages that implement this should also
// implement JSONPBMarshaler so that the custom format can be produced.
//
// The JSON unmarshaling must follow the JSON to proto specification:
//	https://developers.google.com/protocol-buffers/docs/proto3#json
//
// Deprecated: Custom types should implement protobuf reflection instead.
type JSONPBUnmarshaler interface {
	UnmarshalJSONPB(*Unmarshaler, []byte) error
}

// Unmarshal unmarshals a JSON object from r into m.
func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error {
	return u.UnmarshalNext(json.NewDecoder(r), m)
}

// UnmarshalNext unmarshals the next JSON object from d into m.
func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error {
	if m == nil {
		return errors.New("invalid nil message")
	}

	// Parse the next JSON object from the stream.
	raw := json.RawMessage{}
	if err := d.Decode(&raw); err != nil {
		return err
	}

	// Check for custom unmarshalers first since they may not properly
	// implement protobuf reflection that the logic below relies on.
	if jsu, ok := m.(JSONPBUnmarshaler); ok {
		return jsu.UnmarshalJSONPB(u, raw)
	}

	mr := proto.MessageReflect(m)

	// NOTE: For historical reasons, a top-level null is treated as a noop.
	// This is incorrect, but kept for compatibility.
	if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" {
		return nil
	}

	if wrapJSONUnmarshalV2 {
		// NOTE: If input message is non-empty, we need to preserve merge semantics
		// of the old jsonpb implementation. These semantics are not supported by
		// the protobuf JSON specification.
		isEmpty := true
		mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool {
			isEmpty = false // at least one iteration implies non-empty
			return false
		})
		if !isEmpty {
			// Perform unmarshaling into a newly allocated, empty message.
			mr = mr.New()

			// Use a defer to copy all unmarshaled fields into the original message.
			dst := proto.MessageReflect(m)
			defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
				dst.Set(fd, v)
				return true
			})
		}

		// Unmarshal using the v2 JSON unmarshaler.
		opts := protojson.UnmarshalOptions{
			DiscardUnknown: u.AllowUnknownFields,
		}
		if u.AnyResolver != nil {
			opts.Resolver = anyResolver{u.AnyResolver}
		}
		return opts.Unmarshal(raw, mr.Interface())
	} else {
		if err := u.unmarshalMessage(mr, raw); err != nil {
			return err
		}
		return protoV2.CheckInitialized(mr.Interface())
	}
}

func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error {
	md := m.Descriptor()
	fds := md.Fields()

	if string(in) == "null" && md.FullName() != "google.protobuf.Value" {
		return nil
	}

	if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok {
		return jsu.UnmarshalJSONPB(u, in)
	}

	switch wellKnownType(md.FullName()) {
	case "Any":
		var jsonObject map[string]json.RawMessage
		if err := json.Unmarshal(in, &jsonObject); err != nil {
			return err
		}

		rawTypeURL, ok := jsonObject["@type"]
		if !ok {
			return errors.New("Any JSON doesn't have '@type'")
		}
		typeURL, err := unquoteString(string(rawTypeURL))
		if err != nil {
			return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL)
		}
		m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL))

		var m2 protoreflect.Message
		if u.AnyResolver != nil {
			mi, err := u.AnyResolver.Resolve(typeURL)
			if err != nil {
				return err
			}
			m2 = proto.MessageReflect(mi)
		} else {
			mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL)
			if err != nil {
				if err == protoregistry.NotFound {
					return fmt.Errorf("could not resolve Any message type: %v", typeURL)
				}
				return err
			}
			m2 = mt.New()
		}

		if wellKnownType(m2.Descriptor().FullName()) != "" {
			rawValue, ok := jsonObject["value"]
			if !ok {
				return errors.New("Any JSON doesn't have 'value'")
			}
			if err := u.unmarshalMessage(m2, rawValue); err != nil {
				return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
			}
		} else {
			delete(jsonObject, "@type")
			rawJSON, err := json.Marshal(jsonObject)
			if err != nil {
				return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err)
			}
			if err = u.unmarshalMessage(m2, rawJSON); err != nil {
				return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
			}
		}

		rawWire, err := protoV2.Marshal(m2.Interface())
		if err != nil {
			return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err)
		}
		m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire))
		return nil
	case "BoolValue", "BytesValue", "StringValue",
		"Int32Value", "UInt32Value", "FloatValue",
		"Int64Value", "UInt64Value", "DoubleValue":
		fd := fds.ByNumber(1)
		v, err := u.unmarshalValue(m.NewField(fd), in, fd)
		if err != nil {
			return err
		}
		m.Set(fd, v)
		return nil
	case "Duration":
		v, err := unquoteString(string(in))
		if err != nil {
			return err
		}
		d, err := time.ParseDuration(v)
		if err != nil {
			return fmt.Errorf("bad Duration: %v", err)
		}

		sec := d.Nanoseconds() / 1e9
		nsec := d.Nanoseconds() % 1e9
		m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
		m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
		return nil
	case "Timestamp":
		v, err := unquoteString(string(in))
		if err != nil {
			return err
		}
		t, err := time.Parse(time.RFC3339Nano, v)
		if err != nil {
			return fmt.Errorf("bad Timestamp: %v", err)
		}

		sec := t.Unix()
		nsec := t.Nanosecond()
		m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
		m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
		return nil
	case "Value":
		switch {
		case string(in) == "null":
			m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0))
		case string(in) == "true":
			m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true))
		case string(in) == "false":
			m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false))
		case hasPrefixAndSuffix('"', in, '"'):
			s, err := unquoteString(string(in))
			if err != nil {
				return fmt.Errorf("unrecognized type for Value %q", in)
			}
			m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s))
		case hasPrefixAndSuffix('[', in, ']'):
			v := m.Mutable(fds.ByNumber(6))
			return u.unmarshalMessage(v.Message(), in)
		case hasPrefixAndSuffix('{', in, '}'):
			v := m.Mutable(fds.ByNumber(5))
			return u.unmarshalMessage(v.Message(), in)
		default:
			f, err := strconv.ParseFloat(string(in), 0)
			if err != nil {
				return fmt.Errorf("unrecognized type for Value %q", in)
			}
			m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f))
		}
		return nil
	case "ListValue":
		var jsonArray []json.RawMessage
		if err := json.Unmarshal(in, &jsonArray); err != nil {
			return fmt.Errorf("bad ListValue: %v", err)
		}

		lv := m.Mutable(fds.ByNumber(1)).List()
		for _, raw := range jsonArray {
			ve := lv.NewElement()
			if err := u.unmarshalMessage(ve.Message(), raw); err != nil {
				return err
			}
			lv.Append(ve)
		}
		return nil
	case "Struct":
		var jsonObject map[string]json.RawMessage
		if err := json.Unmarshal(in, &jsonObject); err != nil {
			return fmt.Errorf("bad StructValue: %v", err)
		}

		mv := m.Mutable(fds.ByNumber(1)).Map()
		for key, raw := range jsonObject {
			kv := protoreflect.ValueOf(key).MapKey()
			vv := mv.NewValue()
			if err := u.unmarshalMessage(vv.Message(), raw); err != nil {
				return fmt.Errorf("bad value in StructValue for key %q: %v", key, err)
			}
			mv.Set(kv, vv)
		}
		return nil
	}

	var jsonObject map[string]json.RawMessage
	if err := json.Unmarshal(in, &jsonObject); err != nil {
		return err
	}

	// Handle known fields.
	for i := 0; i < fds.Len(); i++ {
		fd := fds.Get(i)
		if fd.IsWeak() && fd.Message().IsPlaceholder() {
			continue //  weak reference is not linked in
		}

		// Search for any raw JSON value associated with this field.
		var raw json.RawMessage
		name := string(fd.Name())
		if fd.Kind() == protoreflect.GroupKind {
			name = string(fd.Message().Name())
		}
		if v, ok := jsonObject[name]; ok {
			delete(jsonObject, name)
			raw = v
		}
		name = string(fd.JSONName())
		if v, ok := jsonObject[name]; ok {
			delete(jsonObject, name)
			raw = v
		}

		// Unmarshal the field value.
		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd)) {
			continue
		}
		v, err := u.unmarshalValue(m.NewField(fd), raw, fd)
		if err != nil {
			return err
		}
		m.Set(fd, v)
	}

	// Handle extension fields.
	for name, raw := range jsonObject {
		if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") {
			continue
		}

		// Resolve the extension field by name.
		xname := protoreflect.FullName(name[len("[") : len(name)-len("]")])
		xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname)
		if xt == nil && isMessageSet(md) {
			xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension"))
		}
		if xt == nil {
			continue
		}
		delete(jsonObject, name)
		fd := xt.TypeDescriptor()
		if fd.ContainingMessage().FullName() != m.Descriptor().FullName() {
			return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName())
		}

		// Unmarshal the field value.
		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd)) {
			continue
		}
		v, err := u.unmarshalValue(m.NewField(fd), raw, fd)
		if err != nil {
			return err
		}
		m.Set(fd, v)
	}

	if !u.AllowUnknownFields && len(jsonObject) > 0 {
		for name := range jsonObject {
			return fmt.Errorf("unknown field %q in %v", name, md.FullName())
		}
	}
	return nil
}

func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
	if md := fd.Message(); md != nil {
		return md.FullName() == "google.protobuf.Value" && fd.Cardinality() != protoreflect.Repeated
	}
	return false
}

func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
	switch {
	case fd.IsList():
		var jsonArray []json.RawMessage
		if err := json.Unmarshal(in, &jsonArray); err != nil {
			return v, err
		}
		lv := v.List()
		for _, raw := range jsonArray {
			ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd)
			if err != nil {
				return v, err
			}
			lv.Append(ve)
		}
		return v, nil
	case fd.IsMap():
		var jsonObject map[string]json.RawMessage
		if err := json.Unmarshal(in, &jsonObject); err != nil {
			return v, err
		}
		kfd := fd.MapKey()
		vfd := fd.MapValue()
		mv := v.Map()
		for key, raw := range jsonObject {
			var kv protoreflect.MapKey
			if kfd.Kind() == protoreflect.StringKind {
				kv = protoreflect.ValueOf(key).MapKey()
			} else {
				v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd)
				if err != nil {
					return v, err
				}
				kv = v.MapKey()
			}

			vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd)
			if err != nil {
				return v, err
			}
			mv.Set(kv, vv)
		}
		return v, nil
	default:
		return u.unmarshalSingularValue(v, in, fd)
	}
}

var nonFinite = map[string]float64{
	`"NaN"`:       math.NaN(),
	`"Infinity"`:  math.Inf(+1),
	`"-Infinity"`: math.Inf(-1),
}

func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
	switch fd.Kind() {
	case protoreflect.BoolKind:
		return unmarshalValue(in, new(bool))
	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
		return unmarshalValue(trimQuote(in), new(int32))
	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
		return unmarshalValue(trimQuote(in), new(int64))
	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
		return unmarshalValue(trimQuote(in), new(uint32))
	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
		return unmarshalValue(trimQuote(in), new(uint64))
	case protoreflect.FloatKind:
		if f, ok := nonFinite[string(in)]; ok {
			return protoreflect.ValueOfFloat32(float32(f)), nil
		}
		return unmarshalValue(trimQuote(in), new(float32))
	case protoreflect.DoubleKind:
		if f, ok := nonFinite[string(in)]; ok {
			return protoreflect.ValueOfFloat64(float64(f)), nil
		}
		return unmarshalValue(trimQuote(in), new(float64))
	case protoreflect.StringKind:
		return unmarshalValue(in, new(string))
	case protoreflect.BytesKind:
		return unmarshalValue(in, new([]byte))
	case protoreflect.EnumKind:
		if hasPrefixAndSuffix('"', in, '"') {
			vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in)))
			if vd == nil {
				return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName())
			}
			return protoreflect.ValueOfEnum(vd.Number()), nil
		}
		return unmarshalValue(in, new(protoreflect.EnumNumber))
	case protoreflect.MessageKind, protoreflect.GroupKind:
		err := u.unmarshalMessage(v.Message(), in)
		return v, err
	default:
		panic(fmt.Sprintf("invalid kind %v", fd.Kind()))
	}
}

func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) {
	err := json.Unmarshal(in, v)
	return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err
}

func unquoteString(in string) (out string, err error) {
	err = json.Unmarshal([]byte(in), &out)
	return out, err
}

func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool {
	if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix {
		return true
	}
	return false
}

// trimQuote is like unquoteString but simply strips surrounding quotes.
// This is incorrect, but is behavior done by the legacy implementation.
func trimQuote(in []byte) []byte {
	if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' {
		in = in[1 : len(in)-1]
	}
	return in
}
