package codec

import "github.com/golang/protobuf/proto"

// EncodeVarint writes a varint-encoded integer to the Buffer.
// This is the format for the
// int32, int64, uint32, uint64, bool, and enum
// protocol buffer types.
func (cb *Buffer) EncodeVarint(x uint64) error {
	for x >= 1<<7 {
		cb.buf = append(cb.buf, uint8(x&0x7f|0x80))
		x >>= 7
	}
	cb.buf = append(cb.buf, uint8(x))
	return nil
}

// EncodeTagAndWireType encodes the given field tag and wire type to the
// buffer. This combines the two values and then writes them as a varint.
func (cb *Buffer) EncodeTagAndWireType(tag int32, wireType int8) error {
	v := uint64((int64(tag) << 3) | int64(wireType))
	return cb.EncodeVarint(v)
}

// EncodeFixed64 writes a 64-bit integer to the Buffer.
// This is the format for the
// fixed64, sfixed64, and double protocol buffer types.
func (cb *Buffer) EncodeFixed64(x uint64) error {
	cb.buf = append(cb.buf,
		uint8(x),
		uint8(x>>8),
		uint8(x>>16),
		uint8(x>>24),
		uint8(x>>32),
		uint8(x>>40),
		uint8(x>>48),
		uint8(x>>56))
	return nil
}

// EncodeFixed32 writes a 32-bit integer to the Buffer.
// This is the format for the
// fixed32, sfixed32, and float protocol buffer types.
func (cb *Buffer) EncodeFixed32(x uint64) error {
	cb.buf = append(cb.buf,
		uint8(x),
		uint8(x>>8),
		uint8(x>>16),
		uint8(x>>24))
	return nil
}

// EncodeZigZag64 does zig-zag encoding to convert the given
// signed 64-bit integer into a form that can be expressed
// efficiently as a varint, even for negative values.
func EncodeZigZag64(v int64) uint64 {
	return (uint64(v) << 1) ^ uint64(v>>63)
}

// EncodeZigZag32 does zig-zag encoding to convert the given
// signed 32-bit integer into a form that can be expressed
// efficiently as a varint, even for negative values.
func EncodeZigZag32(v int32) uint64 {
	return uint64((uint32(v) << 1) ^ uint32((v >> 31)))
}

// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
// This is the format used for the bytes protocol buffer
// type and for embedded messages.
func (cb *Buffer) EncodeRawBytes(b []byte) error {
	if err := cb.EncodeVarint(uint64(len(b))); err != nil {
		return err
	}
	cb.buf = append(cb.buf, b...)
	return nil
}

// EncodeMessage writes the given message to the buffer.
func (cb *Buffer) EncodeMessage(pm proto.Message) error {
	bytes, err := marshalMessage(cb.buf, pm, cb.deterministic)
	if err != nil {
		return err
	}
	cb.buf = bytes
	return nil
}

// EncodeDelimitedMessage writes the given message to the buffer with a
// varint-encoded length prefix (the delimiter).
func (cb *Buffer) EncodeDelimitedMessage(pm proto.Message) error {
	bytes, err := marshalMessage(cb.tmp, pm, cb.deterministic)
	if err != nil {
		return err
	}
	// save truncated buffer if it was grown (so we can re-use it and
	// curtail future allocations)
	if cap(bytes) > cap(cb.tmp) {
		cb.tmp = bytes[:0]
	}
	return cb.EncodeRawBytes(bytes)
}

func marshalMessage(b []byte, pm proto.Message, deterministic bool) ([]byte, error) {
	// we try to use the most efficient way to marshal to existing slice
	nm, ok := pm.(interface {
		// this interface is implemented by generated messages
		XXX_Size() int
		XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
	})
	if ok {
		sz := nm.XXX_Size()
		if cap(b) < len(b)+sz {
			// re-allocate to fit
			bytes := make([]byte, len(b), len(b)+sz)
			copy(bytes, b)
			b = bytes
		}
		return nm.XXX_Marshal(b, deterministic)
	}

	if deterministic {
		// see if the message has custom deterministic methods, preferring an
		// "append" method over one that must always re-allocate
		madm, ok := pm.(interface {
			MarshalAppendDeterministic(b []byte) ([]byte, error)
		})
		if ok {
			return madm.MarshalAppendDeterministic(b)
		}

		mdm, ok := pm.(interface {
			MarshalDeterministic() ([]byte, error)
		})
		if ok {
			bytes, err := mdm.MarshalDeterministic()
			if err != nil {
				return nil, err
			}
			if len(b) == 0 {
				return bytes, nil
			}
			return append(b, bytes...), nil
		}
	}

	mam, ok := pm.(interface {
		// see if we can append the message, vs. having to re-allocate
		MarshalAppend(b []byte) ([]byte, error)
	})
	if ok {
		return mam.MarshalAppend(b)
	}

	// lowest common denominator
	bytes, err := proto.Marshal(pm)
	if err != nil {
		return nil, err
	}
	if len(b) == 0 {
		return bytes, nil
	}
	return append(b, bytes...), nil
}
