// 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"
	"sort"
	"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 wrapJSONMarshalV2 = false

// Marshaler is a configurable object for marshaling protocol buffer messages
// to the specified JSON representation.
type Marshaler struct {
	// OrigName specifies whether to use the original protobuf name for fields.
	OrigName bool

	// EnumsAsInts specifies whether to render enum values as integers,
	// as opposed to string values.
	EnumsAsInts bool

	// EmitDefaults specifies whether to render fields with zero values.
	EmitDefaults bool

	// Indent controls whether the output is compact or not.
	// If empty, the output is compact JSON. Otherwise, every JSON object
	// entry and JSON array value will be on its own line.
	// Each line will be preceded by repeated copies of Indent, where the
	// number of copies is the current indentation depth.
	Indent string

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

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

// Marshal serializes a protobuf message as JSON into w.
func (jm *Marshaler) Marshal(w io.Writer, m proto.Message) error {
	b, err := jm.marshal(m)
	if len(b) > 0 {
		if _, err := w.Write(b); err != nil {
			return err
		}
	}
	return err
}

// MarshalToString serializes a protobuf message as JSON in string form.
func (jm *Marshaler) MarshalToString(m proto.Message) (string, error) {
	b, err := jm.marshal(m)
	if err != nil {
		return "", err
	}
	return string(b), nil
}

func (jm *Marshaler) marshal(m proto.Message) ([]byte, error) {
	v := reflect.ValueOf(m)
	if m == nil || (v.Kind() == reflect.Ptr && v.IsNil()) {
		return nil, errors.New("Marshal called with nil")
	}

	// Check for custom marshalers first since they may not properly
	// implement protobuf reflection that the logic below relies on.
	if jsm, ok := m.(JSONPBMarshaler); ok {
		return jsm.MarshalJSONPB(jm)
	}

	if wrapJSONMarshalV2 {
		opts := protojson.MarshalOptions{
			UseProtoNames:   jm.OrigName,
			UseEnumNumbers:  jm.EnumsAsInts,
			EmitUnpopulated: jm.EmitDefaults,
			Indent:          jm.Indent,
		}
		if jm.AnyResolver != nil {
			opts.Resolver = anyResolver{jm.AnyResolver}
		}
		return opts.Marshal(proto.MessageReflect(m).Interface())
	} else {
		// Check for unpopulated required fields first.
		m2 := proto.MessageReflect(m)
		if err := protoV2.CheckInitialized(m2.Interface()); err != nil {
			return nil, err
		}

		w := jsonWriter{Marshaler: jm}
		err := w.marshalMessage(m2, "", "")
		return w.buf, err
	}
}

type jsonWriter struct {
	*Marshaler
	buf []byte
}

func (w *jsonWriter) write(s string) {
	w.buf = append(w.buf, s...)
}

func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, typeURL string) error {
	if jsm, ok := proto.MessageV1(m.Interface()).(JSONPBMarshaler); ok {
		b, err := jsm.MarshalJSONPB(w.Marshaler)
		if err != nil {
			return err
		}
		if typeURL != "" {
			// we are marshaling this object to an Any type
			var js map[string]*json.RawMessage
			if err = json.Unmarshal(b, &js); err != nil {
				return fmt.Errorf("type %T produced invalid JSON: %v", m.Interface(), err)
			}
			turl, err := json.Marshal(typeURL)
			if err != nil {
				return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err)
			}
			js["@type"] = (*json.RawMessage)(&turl)
			if b, err = json.Marshal(js); err != nil {
				return err
			}
		}
		w.write(string(b))
		return nil
	}

	md := m.Descriptor()
	fds := md.Fields()

	// Handle well-known types.
	const secondInNanos = int64(time.Second / time.Nanosecond)
	switch wellKnownType(md.FullName()) {
	case "Any":
		return w.marshalAny(m, indent)
	case "BoolValue", "BytesValue", "StringValue",
		"Int32Value", "UInt32Value", "FloatValue",
		"Int64Value", "UInt64Value", "DoubleValue":
		fd := fds.ByNumber(1)
		return w.marshalValue(fd, m.Get(fd), indent)
	case "Duration":
		const maxSecondsInDuration = 315576000000
		// "Generated output always contains 0, 3, 6, or 9 fractional digits,
		//  depending on required precision."
		s := m.Get(fds.ByNumber(1)).Int()
		ns := m.Get(fds.ByNumber(2)).Int()
		if s < -maxSecondsInDuration || s > maxSecondsInDuration {
			return fmt.Errorf("seconds out of range %v", s)
		}
		if ns <= -secondInNanos || ns >= secondInNanos {
			return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos)
		}
		if (s > 0 && ns < 0) || (s < 0 && ns > 0) {
			return errors.New("signs of seconds and nanos do not match")
		}
		var sign string
		if s < 0 || ns < 0 {
			sign, s, ns = "-", -1*s, -1*ns
		}
		x := fmt.Sprintf("%s%d.%09d", sign, s, ns)
		x = strings.TrimSuffix(x, "000")
		x = strings.TrimSuffix(x, "000")
		x = strings.TrimSuffix(x, ".000")
		w.write(fmt.Sprintf(`"%vs"`, x))
		return nil
	case "Timestamp":
		// "RFC 3339, where generated output will always be Z-normalized
		//  and uses 0, 3, 6 or 9 fractional digits."
		s := m.Get(fds.ByNumber(1)).Int()
		ns := m.Get(fds.ByNumber(2)).Int()
		if ns < 0 || ns >= secondInNanos {
			return fmt.Errorf("ns out of range [0, %v)", secondInNanos)
		}
		t := time.Unix(s, ns).UTC()
		// time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits).
		x := t.Format("2006-01-02T15:04:05.000000000")
		x = strings.TrimSuffix(x, "000")
		x = strings.TrimSuffix(x, "000")
		x = strings.TrimSuffix(x, ".000")
		w.write(fmt.Sprintf(`"%vZ"`, x))
		return nil
	case "Value":
		// JSON value; which is a null, number, string, bool, object, or array.
		od := md.Oneofs().Get(0)
		fd := m.WhichOneof(od)
		if fd == nil {
			return errors.New("nil Value")
		}
		return w.marshalValue(fd, m.Get(fd), indent)
	case "Struct", "ListValue":
		// JSON object or array.
		fd := fds.ByNumber(1)
		return w.marshalValue(fd, m.Get(fd), indent)
	}

	w.write("{")
	if w.Indent != "" {
		w.write("\n")
	}

	firstField := true
	if typeURL != "" {
		if err := w.marshalTypeURL(indent, typeURL); err != nil {
			return err
		}
		firstField = false
	}

	for i := 0; i < fds.Len(); {
		fd := fds.Get(i)
		if od := fd.ContainingOneof(); od != nil {
			fd = m.WhichOneof(od)
			i += od.Fields().Len()
			if fd == nil {
				continue
			}
		} else {
			i++
		}

		v := m.Get(fd)

		if !m.Has(fd) {
			if !w.EmitDefaults || fd.ContainingOneof() != nil {
				continue
			}
			if fd.Cardinality() != protoreflect.Repeated && (fd.Message() != nil || fd.Syntax() == protoreflect.Proto2) {
				v = protoreflect.Value{} // use "null" for singular messages or proto2 scalars
			}
		}

		if !firstField {
			w.writeComma()
		}
		if err := w.marshalField(fd, v, indent); err != nil {
			return err
		}
		firstField = false
	}

	// Handle proto2 extensions.
	if md.ExtensionRanges().Len() > 0 {
		// Collect a sorted list of all extension descriptor and values.
		type ext struct {
			desc protoreflect.FieldDescriptor
			val  protoreflect.Value
		}
		var exts []ext
		m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
			if fd.IsExtension() {
				exts = append(exts, ext{fd, v})
			}
			return true
		})
		sort.Slice(exts, func(i, j int) bool {
			return exts[i].desc.Number() < exts[j].desc.Number()
		})

		for _, ext := range exts {
			if !firstField {
				w.writeComma()
			}
			if err := w.marshalField(ext.desc, ext.val, indent); err != nil {
				return err
			}
			firstField = false
		}
	}

	if w.Indent != "" {
		w.write("\n")
		w.write(indent)
	}
	w.write("}")
	return nil
}

func (w *jsonWriter) writeComma() {
	if w.Indent != "" {
		w.write(",\n")
	} else {
		w.write(",")
	}
}

func (w *jsonWriter) marshalAny(m protoreflect.Message, indent string) error {
	// "If the Any contains a value that has a special JSON mapping,
	//  it will be converted as follows: {"@type": xxx, "value": yyy}.
	//  Otherwise, the value will be converted into a JSON object,
	//  and the "@type" field will be inserted to indicate the actual data type."
	md := m.Descriptor()
	typeURL := m.Get(md.Fields().ByNumber(1)).String()
	rawVal := m.Get(md.Fields().ByNumber(2)).Bytes()

	var m2 protoreflect.Message
	if w.AnyResolver != nil {
		mi, err := w.AnyResolver.Resolve(typeURL)
		if err != nil {
			return err
		}
		m2 = proto.MessageReflect(mi)
	} else {
		mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL)
		if err != nil {
			return err
		}
		m2 = mt.New()
	}

	if err := protoV2.Unmarshal(rawVal, m2.Interface()); err != nil {
		return err
	}

	if wellKnownType(m2.Descriptor().FullName()) == "" {
		return w.marshalMessage(m2, indent, typeURL)
	}

	w.write("{")
	if w.Indent != "" {
		w.write("\n")
	}
	if err := w.marshalTypeURL(indent, typeURL); err != nil {
		return err
	}
	w.writeComma()
	if w.Indent != "" {
		w.write(indent)
		w.write(w.Indent)
		w.write(`"value": `)
	} else {
		w.write(`"value":`)
	}
	if err := w.marshalMessage(m2, indent+w.Indent, ""); err != nil {
		return err
	}
	if w.Indent != "" {
		w.write("\n")
		w.write(indent)
	}
	w.write("}")
	return nil
}

func (w *jsonWriter) marshalTypeURL(indent, typeURL string) error {
	if w.Indent != "" {
		w.write(indent)
		w.write(w.Indent)
	}
	w.write(`"@type":`)
	if w.Indent != "" {
		w.write(" ")
	}
	b, err := json.Marshal(typeURL)
	if err != nil {
		return err
	}
	w.write(string(b))
	return nil
}

// marshalField writes field description and value to the Writer.
func (w *jsonWriter) marshalField(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
	if w.Indent != "" {
		w.write(indent)
		w.write(w.Indent)
	}
	w.write(`"`)
	switch {
	case fd.IsExtension():
		// For message set, use the fname of the message as the extension name.
		name := string(fd.FullName())
		if isMessageSet(fd.ContainingMessage()) {
			name = strings.TrimSuffix(name, ".message_set_extension")
		}

		w.write("[" + name + "]")
	case w.OrigName:
		name := string(fd.Name())
		if fd.Kind() == protoreflect.GroupKind {
			name = string(fd.Message().Name())
		}
		w.write(name)
	default:
		w.write(string(fd.JSONName()))
	}
	w.write(`":`)
	if w.Indent != "" {
		w.write(" ")
	}
	return w.marshalValue(fd, v, indent)
}

func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
	switch {
	case fd.IsList():
		w.write("[")
		comma := ""
		lv := v.List()
		for i := 0; i < lv.Len(); i++ {
			w.write(comma)
			if w.Indent != "" {
				w.write("\n")
				w.write(indent)
				w.write(w.Indent)
				w.write(w.Indent)
			}
			if err := w.marshalSingularValue(fd, lv.Get(i), indent+w.Indent); err != nil {
				return err
			}
			comma = ","
		}
		if w.Indent != "" {
			w.write("\n")
			w.write(indent)
			w.write(w.Indent)
		}
		w.write("]")
		return nil
	case fd.IsMap():
		kfd := fd.MapKey()
		vfd := fd.MapValue()
		mv := v.Map()

		// Collect a sorted list of all map keys and values.
		type entry struct{ key, val protoreflect.Value }
		var entries []entry
		mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
			entries = append(entries, entry{k.Value(), v})
			return true
		})
		sort.Slice(entries, func(i, j int) bool {
			switch kfd.Kind() {
			case protoreflect.BoolKind:
				return !entries[i].key.Bool() && entries[j].key.Bool()
			case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
				return entries[i].key.Int() < entries[j].key.Int()
			case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
				return entries[i].key.Uint() < entries[j].key.Uint()
			case protoreflect.StringKind:
				return entries[i].key.String() < entries[j].key.String()
			default:
				panic("invalid kind")
			}
		})

		w.write(`{`)
		comma := ""
		for _, entry := range entries {
			w.write(comma)
			if w.Indent != "" {
				w.write("\n")
				w.write(indent)
				w.write(w.Indent)
				w.write(w.Indent)
			}

			s := fmt.Sprint(entry.key.Interface())
			b, err := json.Marshal(s)
			if err != nil {
				return err
			}
			w.write(string(b))

			w.write(`:`)
			if w.Indent != "" {
				w.write(` `)
			}

			if err := w.marshalSingularValue(vfd, entry.val, indent+w.Indent); err != nil {
				return err
			}
			comma = ","
		}
		if w.Indent != "" {
			w.write("\n")
			w.write(indent)
			w.write(w.Indent)
		}
		w.write(`}`)
		return nil
	default:
		return w.marshalSingularValue(fd, v, indent)
	}
}

func (w *jsonWriter) marshalSingularValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
	switch {
	case !v.IsValid():
		w.write("null")
		return nil
	case fd.Message() != nil:
		return w.marshalMessage(v.Message(), indent+w.Indent, "")
	case fd.Enum() != nil:
		if fd.Enum().FullName() == "google.protobuf.NullValue" {
			w.write("null")
			return nil
		}

		vd := fd.Enum().Values().ByNumber(v.Enum())
		if vd == nil || w.EnumsAsInts {
			w.write(strconv.Itoa(int(v.Enum())))
		} else {
			w.write(`"` + string(vd.Name()) + `"`)
		}
		return nil
	default:
		switch v.Interface().(type) {
		case float32, float64:
			switch {
			case math.IsInf(v.Float(), +1):
				w.write(`"Infinity"`)
				return nil
			case math.IsInf(v.Float(), -1):
				w.write(`"-Infinity"`)
				return nil
			case math.IsNaN(v.Float()):
				w.write(`"NaN"`)
				return nil
			}
		case int64, uint64:
			w.write(fmt.Sprintf(`"%d"`, v.Interface()))
			return nil
		}

		b, err := json.Marshal(v.Interface())
		if err != nil {
			return err
		}
		w.write(string(b))
		return nil
	}
}
