// 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 jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok {
		return jsu.UnmarshalJSONPB(u, in)
	}

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

	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
		}

		field := m.NewField(fd)
		// Unmarshal the field value.
		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
			continue
		}
		v, err := u.unmarshalValue(field, 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())
		}

		field := m.NewField(fd)
		// Unmarshal the field value.
		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
			continue
		}
		v, err := u.unmarshalValue(field, 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 isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool {
	if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated {
		_, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler)
		return ok
	}
	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
}
