// Copyright 2019 The Wuffs 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
//
//    https://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 rac provides access to RAC (Random Access Compression) files.
//
// RAC is just a container format, and this package ("rac") is a relatively
// low-level. Users will typically want to process a particular compression
// format wrapped in RAC, such as (RAC + Zlib). For that, look at e.g. the
// sibling "raczlib" package.
//
// The RAC specification is at
// https://github.com/google/wuffs/blob/master/doc/spec/rac-spec.md
package rac

import (
	"errors"
)

const (
	// MaxSize is the maximum RAC file size (in both CSpace and DSpace).
	MaxSize = (1 << 48) - 1

	// invalidCOffsetCLength is ((1 << 64) - 1).
	invalidCOffsetCLength = 0xFFFFFFFFFFFFFFFF
)

// Codec is the compression codec for the RAC file.
//
// For leaf nodes, there are two categories of valid Codecs: Short and Long. A
// Short Codec's uint64 value's high 2 bits and low 56 bits must be zero. A
// Long Codec's uint64 value's high 8 bits must be one and then 7 zeroes.
// Symbolically, Short and Long match:
//   - 0b00??????_00000000_00000000_00000000_00000000_00000000_00000000_00000000
//   - 0b10000000_????????_????????_????????_????????_????????_????????_????????
//
// In terms of the RAC file format, a Short Codec fits in a single byte: the
// Codec Byte in the middle of a branch node. A Long Codec uses that Codec Byte
// to locate 7 other bytes, a location which would otherwise form a "CPtr|CLen"
// value. When converting from the 7 bytes in the wire format to this Go type
// (a uint64 value), they are read little-endian: the "CPtr" bytes are the low
// 6 bytes, the "CLen" is the second-highest byte and the highest byte is
// hard-coded to 0x80.
//
// For example, the 7 bytes "mdo2\x00\x00\x00" would correspond to a Codec
// value of 0x8000_0000_326F_646D.
//
// The Mix Bit is not part of the uint64 representation. Neither is a Long
// Codec's 'c64' index. This package's exported API deals with leaf nodes.
// Branch nodes' wire formats are internal implementation details.
//
// See the RAC specification for further discussion.
type Codec uint64

func (c Codec) isLong() bool  { return int64(c) < 0 }
func (c Codec) isShort() bool { return int64(c) >= 0 }

// Valid returns whether c matches the Short or Long pattern.
func (c Codec) Valid() bool {
	if (c >> 63) == 0 {
		return ((c << 8) == 0) && ((c >> 62) == 0)
	}
	return (c >> 56) == 0x80
}

func (c Codec) name() string {
	if c.isShort() && c.Valid() {
		switch c >> 56 {
		case 0:
			return "Zeroes"
		case 1:
			return "Zlib"
		case 2:
			return "LZ4"
		case 3:
			return "Zstandard"
		}
	}
	return ""
}

func parentChildCodecsValid(parent Codec, child Codec, parentHasMixBit bool) bool {
	return (parent == child) || parentHasMixBit
}

const (
	CodecZeroes    = Codec(0x00 << 56)
	CodecZlib      = Codec(0x01 << 56)
	CodecLZ4       = Codec(0x02 << 56)
	CodecZstandard = Codec(0x03 << 56)

	codecMixBit     = Codec(1 << 62)
	codecLongZeroes = Codec(1 << 63)
	CodecInvalid    = Codec((1 << 64) - 1)
)

// IndexLocation is whether the index is at the start or end of the RAC file.
//
// See the RAC specification for further discussion.
type IndexLocation uint8

const magic = "\x72\xC3\x63"

const (
	IndexLocationAtEnd   = IndexLocation(0)
	IndexLocationAtStart = IndexLocation(1)
)

var indexLocationAtEndMagic = []byte("\x72\xC3\x63\x00")

var (
	ErrCodecWriterDoesNotSupportCChunkSize = errors.New("rac: CodecWriter does not support CChunkSize")

	errAlreadyClosed                 = errors.New("rac: already closed")
	errCChunkSizeIsTooSmall          = errors.New("rac: CChunkSize is too small")
	errILAEndTempFile                = errors.New("rac: IndexLocationAtEnd requires a nil TempFile")
	errILAStartTempFile              = errors.New("rac: IndexLocationAtStart requires a non-nil TempFile")
	errInconsistentCompressedSize    = errors.New("rac: inconsistent compressed size")
	errInvalidCPageSize              = errors.New("rac: invalid CPageSize")
	errInvalidChunk                  = errors.New("rac: invalid chunk")
	errInvalidChunkTooLarge          = errors.New("rac: invalid chunk (too large)")
	errInvalidChunkTruncated         = errors.New("rac: invalid chunk (truncated)")
	errInvalidCodec                  = errors.New("rac: invalid Codec")
	errInvalidCodecWriter            = errors.New("rac: invalid CodecWriter")
	errInvalidCompressedSize         = errors.New("rac: invalid CompressedSize")
	errInvalidIndexNode              = errors.New("rac: invalid index node")
	errInvalidInputMissingMagicBytes = errors.New("rac: invalid input: missing magic bytes")
	errInvalidInputMissingRootNode   = errors.New("rac: invalid input: missing root node")
	errInvalidReadSeeker             = errors.New("rac: invalid ReadSeeker")
	errInvalidWriter                 = errors.New("rac: invalid Writer")
	errSeekToInvalidWhence           = errors.New("rac: seek to invalid whence")
	errSeekToNegativePosition        = errors.New("rac: seek to negative position")
	errSeekToNegativeRange           = errors.New("rac: seek to negative range")
	errTooManyChunks                 = errors.New("rac: too many chunks")
	errTooManyResources              = errors.New("rac: too many resources")
	errTooMuchInput                  = errors.New("rac: too much input")
	errUnsupportedRACFileVersion     = errors.New("rac: unsupported RAC file version")

	errInternalArityIsTooLarge      = errors.New("rac: internal error: arity is too large")
	errInternalEmptyDRange          = errors.New("rac: internal error: empty DRange")
	errInternalInconsistentArity    = errors.New("rac: internal error: inconsistent arity")
	errInternalInconsistentPosition = errors.New("rac: internal error: inconsistent position")
	errInternalShortCSize           = errors.New("rac: internal error: short CSize")
)
