package dynamic

// Binary serialization and de-serialization for dynamic messages

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	"github.com/jhump/protoreflect/codec"
	"io"
)

// defaultDeterminism, if true, will mean that calls to Marshal will produce
// deterministic output. This is used to make the output of proto.Marshal(...)
// deterministic (since there is no way to have that convey determinism intent).
// **This is only used from tests.**
var defaultDeterminism = false

// Marshal serializes this message to bytes, returning an error if the operation
// fails. The resulting bytes are in the standard protocol buffer binary format.
func (m *Message) Marshal() ([]byte, error) {
	var b codec.Buffer
	b.SetDeterministic(defaultDeterminism)
	if err := m.marshal(&b); err != nil {
		return nil, err
	}
	return b.Bytes(), nil
}

// MarshalAppend behaves exactly the same as Marshal, except instead of allocating a
// new byte slice to marshal into, it uses the provided byte slice. The backing array
// for the returned byte slice *may* be the same as the one that was passed in, but
// it's not guaranteed as a new backing array will automatically be allocated if
// more bytes need to be written than the provided buffer has capacity for.
func (m *Message) MarshalAppend(b []byte) ([]byte, error) {
	codedBuf := codec.NewBuffer(b)
	codedBuf.SetDeterministic(defaultDeterminism)
	if err := m.marshal(codedBuf); err != nil {
		return nil, err
	}
	return codedBuf.Bytes(), nil
}

// MarshalDeterministic serializes this message to bytes in a deterministic way,
// returning an error if the operation fails. This differs from Marshal in that
// map keys will be sorted before serializing to bytes. The protobuf spec does
// not define ordering for map entries, so Marshal will use standard Go map
// iteration order (which will be random). But for cases where determinism is
// more important than performance, use this method instead.
func (m *Message) MarshalDeterministic() ([]byte, error) {
	var b codec.Buffer
	b.SetDeterministic(true)
	if err := m.marshal(&b); err != nil {
		return nil, err
	}
	return b.Bytes(), nil
}

// MarshalAppendDeterministic behaves exactly the same as MarshalDeterministic,
// except instead of allocating a new byte slice to marshal into, it uses the
// provided byte slice. The backing array for the returned byte slice *may* be
// the same as the one that was passed in, but it's not guaranteed as a new
// backing array will automatically be allocated if more bytes need to be written
// than the provided buffer has capacity for.
func (m *Message) MarshalAppendDeterministic(b []byte) ([]byte, error) {
	codedBuf := codec.NewBuffer(b)
	codedBuf.SetDeterministic(true)
	if err := m.marshal(codedBuf); err != nil {
		return nil, err
	}
	return codedBuf.Bytes(), nil
}

func (m *Message) marshal(b *codec.Buffer) error {
	if err := m.marshalKnownFields(b); err != nil {
		return err
	}
	return m.marshalUnknownFields(b)
}

func (m *Message) marshalKnownFields(b *codec.Buffer) error {
	for _, tag := range m.knownFieldTags() {
		itag := int32(tag)
		val := m.values[itag]
		fd := m.FindFieldDescriptor(itag)
		if fd == nil {
			panic(fmt.Sprintf("Couldn't find field for tag %d", itag))
		}
		if err := b.EncodeFieldValue(fd, val); err != nil {
			return err
		}
	}
	return nil
}

func (m *Message) marshalUnknownFields(b *codec.Buffer) error {
	for _, tag := range m.unknownFieldTags() {
		itag := int32(tag)
		sl := m.unknownFields[itag]
		for _, u := range sl {
			if err := b.EncodeTagAndWireType(itag, u.Encoding); err != nil {
				return err
			}
			switch u.Encoding {
			case proto.WireBytes:
				if err := b.EncodeRawBytes(u.Contents); err != nil {
					return err
				}
			case proto.WireStartGroup:
				_, _ = b.Write(u.Contents)
				if err := b.EncodeTagAndWireType(itag, proto.WireEndGroup); err != nil {
					return err
				}
			case proto.WireFixed32:
				if err := b.EncodeFixed32(u.Value); err != nil {
					return err
				}
			case proto.WireFixed64:
				if err := b.EncodeFixed64(u.Value); err != nil {
					return err
				}
			case proto.WireVarint:
				if err := b.EncodeVarint(u.Value); err != nil {
					return err
				}
			default:
				return codec.ErrBadWireType
			}
		}
	}
	return nil
}

// Unmarshal de-serializes the message that is present in the given bytes into
// this message. It first resets the current message. It returns an error if the
// given bytes do not contain a valid encoding of this message type.
func (m *Message) Unmarshal(b []byte) error {
	m.Reset()
	if err := m.UnmarshalMerge(b); err != nil {
		return err
	}
	return m.Validate()
}

// UnmarshalMerge de-serializes the message that is present in the given bytes
// into this message. Unlike Unmarshal, it does not first reset the message,
// instead merging the data in the given bytes into the existing data in this
// message.
func (m *Message) UnmarshalMerge(b []byte) error {
	return m.unmarshal(codec.NewBuffer(b), false)
}

func (m *Message) unmarshal(buf *codec.Buffer, isGroup bool) error {
	for !buf.EOF() {
		fd, val, err := buf.DecodeFieldValue(m.FindFieldDescriptor, m.mf)
		if err != nil {
			if err == codec.ErrWireTypeEndGroup {
				if isGroup {
					// finished parsing group
					return nil
				}
				return codec.ErrBadWireType
			}
			return err
		}

		if fd == nil {
			if m.unknownFields == nil {
				m.unknownFields = map[int32][]UnknownField{}
			}
			uv := val.(codec.UnknownField)
			u := UnknownField{
				Encoding: uv.Encoding,
				Value:    uv.Value,
				Contents: uv.Contents,
			}
			m.unknownFields[uv.Tag] = append(m.unknownFields[uv.Tag], u)
		} else if err := mergeField(m, fd, val); err != nil {
			return err
		}
	}
	if isGroup {
		return io.ErrUnexpectedEOF
	}
	return nil
}
