// Copyright 2015 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmpbin

import (
	"bytes"
)

// WriteableBytesBuffer is the interface which corresponds to the subset of
// *bytes.Buffer required for writing.
type WriteableBytesBuffer interface {
	ReadableBytesBuffer

	String() string
	Bytes() []byte

	Grow(int)

	Write([]byte) (int, error)
	WriteByte(c byte) error
	WriteString(s string) (int, error)
}

// ReadableBytesBuffer is the interface which corresponds to the subset of
// *bytes.Reader required for reading.
type ReadableBytesBuffer interface {
	Len() int

	Read([]byte) (int, error)
	ReadByte() (byte, error)
}

var (
	_ WriteableBytesBuffer = (*bytes.Buffer)(nil)
	_ ReadableBytesBuffer  = (*bytes.Reader)(nil)
)

// InvertibleBytesBuffer is just like Buffer, except that it also has a stateful
// SetInvert() method, which will cause all reads and writes to/from it to be
// inverted (e.g. every byte XOR 0xFF).
//
// In contexts where you need comparable byte sequences, like datastore queries,
// it requires manipulating the sortable fields (e.g. synthesizing them,
// parsing them, etc.). In particular, when you have a reverse-sorted field
// (e.g. high to low instead of low to high), it's achieved by having all the
// bits inverted.
//
// Serialization formats (like gae/service/datastore.Serialize) can include
// delimiter information, which the parsers only know to parse non-inverted. If
// we don't have this Invertible buffer, we'd basically have to invert every
// byte in the []byte array when we're trying to decode a reverse-ordered field
// (including the bytes of all fields after the one we intend to parse) so that
// the parser can consume as many bytes as it needs (and it only knows the
// number of bytes it needs as it decodes them). This InvertibleBytesBuffer
// lets that happen on the fly without having to flip the whole underlying
// []byte.
//
// If you know you need it, you'll know it's the right thing.
// If you're not sure then you definitely don't need it!
//
// See InvertBytes for doing one-off []byte inversions.
type InvertibleBytesBuffer interface {
	WriteableBytesBuffer
	SetInvert(inverted bool)
}

type invertibleBytesBuffer struct {
	WriteableBytesBuffer
	invert bool
}

// Invertible returns an InvertibleBuffer based on the Buffer.
func Invertible(b WriteableBytesBuffer) InvertibleBytesBuffer {
	return &invertibleBytesBuffer{b, false}
}

func (ib *invertibleBytesBuffer) Read(bs []byte) (int, error) {
	n, err := ib.WriteableBytesBuffer.Read(bs)
	if ib.invert {
		for i, b := range bs {
			bs[i] = b ^ 0xFF
		}
	}
	return n, err
}

func (ib *invertibleBytesBuffer) WriteString(s string) (int, error) {
	if ib.invert {
		ib.Grow(len(s))
		for i := 0; i < len(s); i++ {
			if err := ib.WriteableBytesBuffer.WriteByte(s[i] ^ 0xFF); err != nil {
				return i, err
			}
		}
		return len(s), nil
	}
	return ib.WriteableBytesBuffer.WriteString(s)
}

func (ib *invertibleBytesBuffer) Write(bs []byte) (int, error) {
	if ib.invert {
		ib.Grow(len(bs))
		for i, b := range bs {
			if err := ib.WriteableBytesBuffer.WriteByte(b ^ 0xFF); err != nil {
				return i, err
			}
		}
		return len(bs), nil
	}
	return ib.WriteableBytesBuffer.Write(bs)
}

func (ib *invertibleBytesBuffer) WriteByte(b byte) error {
	if ib.invert {
		b = b ^ 0xFF
	}
	return ib.WriteableBytesBuffer.WriteByte(b)
}

func (ib *invertibleBytesBuffer) ReadByte() (byte, error) {
	ret, err := ib.WriteableBytesBuffer.ReadByte()
	if ib.invert {
		ret = ret ^ 0xFF
	}
	return ret, err
}

func (ib *invertibleBytesBuffer) SetInvert(inverted bool) {
	ib.invert = inverted
}
