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

import (
	"fmt"
	"sort"
	"unicode/utf8"

	"google.golang.org/protobuf/internal/encoding/messageset"
	"google.golang.org/protobuf/internal/encoding/text"
	"google.golang.org/protobuf/internal/encoding/wire"
	"google.golang.org/protobuf/internal/errors"
	"google.golang.org/protobuf/internal/fieldnum"
	"google.golang.org/protobuf/internal/flags"
	"google.golang.org/protobuf/internal/mapsort"
	"google.golang.org/protobuf/internal/pragma"
	"google.golang.org/protobuf/proto"
	pref "google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"
)

const defaultIndent = "  "

// Format formats the message as a multiline string.
// This function is only intended for human consumption and ignores errors.
// Do not depend on the output being stable. It may change over time across
// different versions of the program.
func Format(m proto.Message) string {
	return MarshalOptions{Multiline: true}.Format(m)
}

// Marshal writes the given proto.Message in textproto format using default
// options. Do not depend on the output being stable. It may change over time
// across different versions of the program.
func Marshal(m proto.Message) ([]byte, error) {
	return MarshalOptions{}.Marshal(m)
}

// MarshalOptions is a configurable text format marshaler.
type MarshalOptions struct {
	pragma.NoUnkeyedLiterals

	// AllowPartial allows messages that have missing required fields to marshal
	// without returning an error. If AllowPartial is false (the default),
	// Marshal will return error if there are any missing required fields.
	AllowPartial bool

	// EmitUnknown specifies whether to emit unknown fields in the output.
	// If specified, the unmarshaler may be unable to parse the output.
	// The default is to exclude unknown fields.
	EmitUnknown bool

	// Multiline specifies whether the marshaler should format the output in
	// indented-form with every textual element on a new line.
	// If Indent is an empty string, then an arbitrary indent is chosen.
	Multiline bool

	// Indent specifies the set of indentation characters to use in a multiline
	// formatted output such that every entry is preceded by Indent and
	// terminated by a newline. If non-empty, then Multiline is treated as true.
	// Indent can only be composed of space or tab characters.
	Indent string

	// Resolver is used for looking up types when expanding google.protobuf.Any
	// messages. If nil, this defaults to using protoregistry.GlobalTypes.
	Resolver interface {
		protoregistry.ExtensionTypeResolver
		protoregistry.MessageTypeResolver
	}
}

// Format formats the message as a string.
// This method is only intended for human consumption and ignores errors.
// Do not depend on the output being stable. It may change over time across
// different versions of the program.
func (o MarshalOptions) Format(m proto.Message) string {
	if m == nil || !m.ProtoReflect().IsValid() {
		return "<nil>" // invalid syntax, but okay since this is for debugging
	}
	o.AllowPartial = true
	o.EmitUnknown = true
	b, _ := o.Marshal(m)
	return string(b)
}

// Marshal writes the given proto.Message in textproto format using options in
// MarshalOptions object. Do not depend on the output being stable. It may
// change over time across different versions of the program.
func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
	if o.Multiline && o.Indent == "" {
		o.Indent = defaultIndent
	}
	if o.Resolver == nil {
		o.Resolver = protoregistry.GlobalTypes
	}

	v, err := o.marshalMessage(m.ProtoReflect())
	if err != nil {
		return nil, err
	}

	delims := [2]byte{'{', '}'}
	const outputASCII = false
	b, err := text.Marshal(v, o.Indent, delims, outputASCII)
	if err != nil {
		return nil, err
	}
	if o.AllowPartial {
		return b, nil
	}
	return b, proto.IsInitialized(m)
}

// marshalMessage converts a protoreflect.Message to a text.Value.
func (o MarshalOptions) marshalMessage(m pref.Message) (text.Value, error) {
	messageDesc := m.Descriptor()
	if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) {
		return text.Value{}, errors.New("no support for proto1 MessageSets")
	}

	// Handle Any expansion.
	if messageDesc.FullName() == "google.protobuf.Any" {
		if msg, err := o.marshalAny(m); err == nil {
			// Return as is if no error.
			return msg, nil
		}
		// Otherwise continue on to marshal Any as a regular message.
	}

	// Handle known fields.
	var msgFields [][2]text.Value
	fieldDescs := messageDesc.Fields()
	size := fieldDescs.Len()
	for i := 0; i < size; {
		fd := fieldDescs.Get(i)
		if od := fd.ContainingOneof(); od != nil {
			fd = m.WhichOneof(od)
			i += od.Fields().Len()
		} else {
			i++
		}
		if fd == nil || !m.Has(fd) {
			continue
		}

		name := text.ValueOf(fd.Name())
		// Use type name for group field name.
		if fd.Kind() == pref.GroupKind {
			name = text.ValueOf(fd.Message().Name())
		}
		pval := m.Get(fd)
		var err error
		msgFields, err = o.appendField(msgFields, name, pval, fd)
		if err != nil {
			return text.Value{}, err
		}
	}

	// Handle extensions.
	var err error
	msgFields, err = o.appendExtensions(msgFields, m)
	if err != nil {
		return text.Value{}, err
	}

	// Handle unknown fields.
	if o.EmitUnknown {
		msgFields = appendUnknown(msgFields, m.GetUnknown())
	}

	return text.ValueOf(msgFields), nil
}

// appendField marshals a protoreflect.Value and appends it to the given [][2]text.Value.
func (o MarshalOptions) appendField(msgFields [][2]text.Value, name text.Value, pval pref.Value, fd pref.FieldDescriptor) ([][2]text.Value, error) {
	switch {
	case fd.IsList():
		items, err := o.marshalList(pval.List(), fd)
		if err != nil {
			return msgFields, err
		}

		for _, item := range items {
			msgFields = append(msgFields, [2]text.Value{name, item})
		}
	case fd.IsMap():
		items, err := o.marshalMap(pval.Map(), fd)
		if err != nil {
			return msgFields, err
		}

		for _, item := range items {
			msgFields = append(msgFields, [2]text.Value{name, item})
		}
	default:
		tval, err := o.marshalSingular(pval, fd)
		if err != nil {
			return msgFields, err
		}
		msgFields = append(msgFields, [2]text.Value{name, tval})
	}

	return msgFields, nil
}

// marshalSingular converts a non-repeated field value to text.Value.
// This includes all scalar types, enums, messages, and groups.
func (o MarshalOptions) marshalSingular(val pref.Value, fd pref.FieldDescriptor) (text.Value, error) {
	kind := fd.Kind()
	switch kind {
	case pref.BoolKind,
		pref.Int32Kind, pref.Sint32Kind, pref.Uint32Kind,
		pref.Int64Kind, pref.Sint64Kind, pref.Uint64Kind,
		pref.Sfixed32Kind, pref.Fixed32Kind,
		pref.Sfixed64Kind, pref.Fixed64Kind,
		pref.FloatKind, pref.DoubleKind,
		pref.BytesKind:
		return text.ValueOf(val.Interface()), nil

	case pref.StringKind:
		s := val.String()
		if !utf8.ValidString(s) {
			return text.Value{}, errors.InvalidUTF8(string(fd.FullName()))
		}
		return text.ValueOf(s), nil

	case pref.EnumKind:
		num := val.Enum()
		if desc := fd.Enum().Values().ByNumber(num); desc != nil {
			return text.ValueOf(desc.Name()), nil
		}
		// Use numeric value if there is no enum description.
		return text.ValueOf(int32(num)), nil

	case pref.MessageKind, pref.GroupKind:
		return o.marshalMessage(val.Message())
	}

	panic(fmt.Sprintf("%v has unknown kind: %v", fd.FullName(), kind))
}

// marshalList converts a protoreflect.List to []text.Value.
func (o MarshalOptions) marshalList(list pref.List, fd pref.FieldDescriptor) ([]text.Value, error) {
	size := list.Len()
	values := make([]text.Value, 0, size)

	for i := 0; i < size; i++ {
		item := list.Get(i)
		val, err := o.marshalSingular(item, fd)
		if err != nil {
			// Return already marshaled values.
			return values, err
		}
		values = append(values, val)
	}

	return values, nil
}

var (
	mapKeyName   = text.ValueOf(pref.Name("key"))
	mapValueName = text.ValueOf(pref.Name("value"))
)

// marshalMap converts a protoreflect.Map to []text.Value.
func (o MarshalOptions) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) ([]text.Value, error) {
	// values is a list of messages.
	values := make([]text.Value, 0, mmap.Len())

	var err error
	mapsort.Range(mmap, fd.MapKey().Kind(), func(key pref.MapKey, val pref.Value) bool {
		var keyTxtVal text.Value
		keyTxtVal, err = o.marshalSingular(key.Value(), fd.MapKey())
		if err != nil {
			return false
		}
		var valTxtVal text.Value
		valTxtVal, err = o.marshalSingular(val, fd.MapValue())
		if err != nil {
			return false
		}
		// Map entry (message) contains 2 fields, first field for key and second field for value.
		msg := text.ValueOf([][2]text.Value{
			{mapKeyName, keyTxtVal},
			{mapValueName, valTxtVal},
		})
		values = append(values, msg)
		err = nil
		return true
	})
	if err != nil {
		return nil, err
	}

	return values, nil
}

// appendExtensions marshals extension fields and appends them to the given [][2]text.Value.
func (o MarshalOptions) appendExtensions(msgFields [][2]text.Value, m pref.Message) ([][2]text.Value, error) {
	var err error
	var entries [][2]text.Value
	m.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
		if !fd.IsExtension() {
			return true
		}

		// For MessageSet extensions, the name used is the parent message.
		name := fd.FullName()
		if messageset.IsMessageSetExtension(fd) {
			name = name.Parent()
		}

		// Use string type to produce [name] format.
		tname := text.ValueOf(string(name))
		entries, err = o.appendField(entries, tname, v, fd)
		if err != nil {
			return false
		}
		err = nil
		return true
	})
	if err != nil {
		return msgFields, err
	}

	// Sort extensions lexicographically and append to output.
	sort.SliceStable(entries, func(i, j int) bool {
		return entries[i][0].String() < entries[j][0].String()
	})
	return append(msgFields, entries...), nil
}

// appendUnknown parses the given []byte and appends field(s) into the given fields slice.
// This function assumes proper encoding in the given []byte.
func appendUnknown(fields [][2]text.Value, b []byte) [][2]text.Value {
	for len(b) > 0 {
		var value interface{}
		num, wtype, n := wire.ConsumeTag(b)
		b = b[n:]

		switch wtype {
		case wire.VarintType:
			value, n = wire.ConsumeVarint(b)
		case wire.Fixed32Type:
			value, n = wire.ConsumeFixed32(b)
		case wire.Fixed64Type:
			value, n = wire.ConsumeFixed64(b)
		case wire.BytesType:
			value, n = wire.ConsumeBytes(b)
		case wire.StartGroupType:
			var v []byte
			v, n = wire.ConsumeGroup(num, b)
			var msg [][2]text.Value
			value = appendUnknown(msg, v)
		default:
			panic(fmt.Sprintf("error parsing unknown field wire type: %v", wtype))
		}

		fields = append(fields, [2]text.Value{text.ValueOf(uint32(num)), text.ValueOf(value)})
		b = b[n:]
	}
	return fields
}

// marshalAny converts a google.protobuf.Any protoreflect.Message to a text.Value.
func (o MarshalOptions) marshalAny(m pref.Message) (text.Value, error) {
	fds := m.Descriptor().Fields()
	fdType := fds.ByNumber(fieldnum.Any_TypeUrl)
	fdValue := fds.ByNumber(fieldnum.Any_Value)

	typeURL := m.Get(fdType).String()
	value := m.Get(fdValue)

	emt, err := o.Resolver.FindMessageByURL(typeURL)
	if err != nil {
		return text.Value{}, err
	}
	em := emt.New().Interface()
	err = proto.UnmarshalOptions{
		AllowPartial: true,
		Resolver:     o.Resolver,
	}.Unmarshal(value.Bytes(), em)
	if err != nil {
		return text.Value{}, err
	}

	msg, err := o.marshalMessage(em.ProtoReflect())
	if err != nil {
		return text.Value{}, err
	}
	// Expanded Any field value contains only a single field with the type_url field value as the
	// field name in [] and a text marshaled field value of the embedded message.
	msgFields := [][2]text.Value{
		{
			text.ValueOf(typeURL),
			msg,
		},
	}
	return text.ValueOf(msgFields), nil
}
