// 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 racdict provides support for the RAC (Random Access Compression)
// common dictionary format.
//
// See
// https://github.com/google/wuffs/blob/main/doc/spec/rac-spec.md#common-dictionary-format
package racdict

import (
	"errors"
	"hash/crc32"
	"io"

	"github.com/google/wuffs/lib/rac"
)

const (
	// MaxInclLength is the maximum (inclusive) length of a dictionary, not
	// including the length prefix and the checksum suffix.
	//
	// Its value is (1 GiB - 1), or 1_073_741_823 bytes.
	MaxInclLength = (1 << 30) - 1
)

var (
	errDictionaryIsTooLong = errors.New("racdict: dictionary is too long")
	errInvalidDictionary   = errors.New("racdict: invalid dictionary")
)

func u32LE(b []byte) uint32 {
	_ = b[3] // Early bounds check to guarantee safety of reads below.
	return (uint32(b[0]) << 0) |
		(uint32(b[1]) << 8) |
		(uint32(b[2]) << 16) |
		(uint32(b[3]) << 24)
}

// Loader loads a dictionary wrapped in the RAC common dictionary format.
//
// It can cache previously loaded values, keyed by a rac.Chunk.
type Loader struct {
	cachedBytes []byte
	cachedRange rac.Range
	buf         [4]byte
}

// Load reads and unwraps a wrapped dictionary.
func (r *Loader) Load(rs io.ReadSeeker, chunk rac.Chunk) (dictionary []byte, retErr error) {
	if !chunk.CTertiary.Empty() {
		return nil, errInvalidDictionary
	}
	if chunk.CSecondary.Empty() {
		return nil, nil
	}
	cRange := chunk.CSecondary

	// Load from the MRU cache, if it was loaded from the same cRange.
	if (cRange == r.cachedRange) && !cRange.Empty() {
		return r.cachedBytes, nil
	}

	// Check the cRange size and the tTag.
	if (cRange.Size() < 8) || (chunk.TTag != 0xFF) {
		return nil, errInvalidDictionary
	}

	// Read the dictionary size.
	if _, err := rs.Seek(cRange[0], io.SeekStart); err != nil {
		return nil, err
	}
	if _, err := io.ReadFull(rs, r.buf[:4]); err != nil {
		return nil, err
	}

	// Check that the high 2 bits are zero (reserved). In other words, we
	// enforce that the maximum (inclusive) length is MaxInclLength.
	dictSize := int64(u32LE(r.buf[:4]))
	if (dictSize >> 30) != 0 {
		return nil, errInvalidDictionary
	}

	// Check the overall size. The +8 is for the 4 byte prefix (dictionary
	// size) and the 4 byte suffix (checksum).
	if (dictSize + 8) > cRange.Size() {
		return nil, errInvalidDictionary
	}

	// Allocate or re-use the cachedBytes buffer.
	buffer := []byte(nil)
	if n := dictSize + 4; int64(cap(r.cachedBytes)) >= n {
		buffer = r.cachedBytes[:n]
		// Invalidate the cached dictionary, as we are re-using its memory.
		r.cachedRange = rac.Range{}
	} else {
		buffer = make([]byte, n)
	}

	// Read the dictionary and checksum.
	if _, err := io.ReadFull(rs, buffer); err != nil {
		return nil, err
	}

	// Verify the checksum.
	dict, checksum := buffer[:dictSize], buffer[dictSize:]
	if u32LE(checksum) != crc32.ChecksumIEEE(dict) {
		return nil, errInvalidDictionary
	}

	// Save to the MRU cache and return.
	r.cachedBytes = dict
	r.cachedRange = cRange
	return dict, nil
}

// Saver saves a dictionary wrapped in the RAC common dictionary format.
type Saver struct {
	stash []byte
}

// WrapResource wraps a dictionary.
func (w *Saver) WrapResource(
	raw []byte,
	refineResourceData func([]byte) []byte,
) ([]byte, error) {
	refined := refineResourceData(raw)
	if len(refined) > MaxInclLength {
		return nil, errDictionaryIsTooLong
	}
	wrapped := make([]byte, len(refined)+8)
	wrapped[0] = uint8(len(refined) >> 0)
	wrapped[1] = uint8(len(refined) >> 8)
	wrapped[2] = uint8(len(refined) >> 16)
	wrapped[3] = uint8(len(refined) >> 24)
	copy(wrapped[4:], refined)
	checksum := crc32.ChecksumIEEE(refined)
	wrapped[len(wrapped)-4] = uint8(checksum >> 0)
	wrapped[len(wrapped)-3] = uint8(checksum >> 8)
	wrapped[len(wrapped)-2] = uint8(checksum >> 16)
	wrapped[len(wrapped)-1] = uint8(checksum >> 24)
	return wrapped, nil
}

// Compress helps implement rac.CodecWriter.
func (w *Saver) Compress(
	p []byte,
	q []byte,
	resourcesData [][]byte,
	codec rac.Codec,
	compress func(p []byte, q []byte, dict []byte) ([]byte, error),
	refineResourceData func([]byte) []byte,
) (
	retCodec rac.Codec,
	compressed []byte,
	secondaryResource int,
	tertiaryResource int,
	retErr error,
) {
	secondaryResource = rac.NoResourceUsed

	// Compress p+q without any shared dictionary.
	baseline, err := compress(p, q, nil)
	if err != nil {
		return 0, nil, 0, 0, err
	}
	// If there aren't any potential shared dictionaries, or if the baseline
	// compressed form is small, just return the baseline.
	const minBaselineSizeToConsiderDictionaries = 256
	if (len(resourcesData) == 0) || (len(baseline) < minBaselineSizeToConsiderDictionaries) {
		return codec, baseline, secondaryResource, rac.NoResourceUsed, nil
	}

	// w.stash keeps a copy of the best compression so far. Every call to
	// compress can clobber the bytes previously returned by compress.
	w.stash = append(w.stash[:0], baseline...)
	compressed = w.stash

	// Only use a shared dictionary if it results in something smaller than
	// 98.4375% (an arbitrary heuristic threshold) of the baseline. Otherwise,
	// it's arguably not worth the additional complexity.
	threshold := (len(baseline) / 64) * 63

	for i, resourceData := range resourcesData {
		refined := refineResourceData(resourceData)
		if len(refined) > MaxInclLength {
			return 0, nil, 0, 0, errDictionaryIsTooLong
		}

		candidate, err := compress(p, q, refined)
		if err != nil {
			return 0, nil, 0, 0, err
		}
		if n := len(candidate); (n >= threshold) || (n >= len(compressed)) {
			continue
		}
		secondaryResource = i

		// As an optimization, if the final candidate is the winner, we don't
		// have to copy its contents to w.stash.
		if i == len(resourcesData)-1 {
			compressed = candidate
		} else {
			w.stash = append(w.stash[:0], candidate...)
			compressed = w.stash
		}
	}
	return codec, compressed, secondaryResource, rac.NoResourceUsed, nil
}
