// 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/main/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")
)
