// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package triegen implements a code generator for a trie for associating
// unsigned integer values with UTF-8 encoded runes.
//
// Many of the go.text packages use tries for storing per-rune information.  A
// trie is especially useful if many of the runes have the same value. If this
// is the case, many blocks can be expected to be shared allowing for
// information on many runes to be stored in little space.
//
// As most of the lookups are done directly on []byte slices, the tries use the
// UTF-8 bytes directly for the lookup. This saves a conversion from UTF-8 to
// runes and contributes a little bit to better performance. It also naturally
// provides a fast path for ASCII.
//
// Space is also an issue. There are many code points defined in Unicode and as
// a result tables can get quite large. So every byte counts. The triegen
// package automatically chooses the smallest integer values to represent the
// tables. Compacters allow further compression of the trie by allowing for
// alternative representations of individual trie blocks.
//
// triegen allows generating multiple tries as a single structure. This is
// useful when, for example, one wants to generate tries for several languages
// that have a lot of values in common. Some existing libraries for
// internationalization store all per-language data as a dynamically loadable
// chunk. The go.text packages are designed with the assumption that the user
// typically wants to compile in support for all supported languages, in line
// with the approach common to Go to create a single standalone binary. The
// multi-root trie approach can give significant storage savings in this
// scenario.
//
// triegen generates both tables and code. The code is optimized to use the
// automatically chosen data types. The following code is generated for a Trie
// or multiple Tries named "foo":
//	- type fooTrie
//		The trie type.
//
//	- func newFooTrie(x int) *fooTrie
//		Trie constructor, where x is the index of the trie passed to Gen.
//
//	- func (t *fooTrie) lookup(s []byte) (v uintX, sz int)
//		The lookup method, where uintX is automatically chosen.
//
//	- func lookupString, lookupUnsafe and lookupStringUnsafe
//		Variants of the above.
//
//	- var fooValues and fooIndex and any tables generated by Compacters.
//		The core trie data.
//
//	- var fooTrieHandles
//		Indexes of starter blocks in case of multiple trie roots.
//
// It is recommended that users test the generated trie by checking the returned
// value for every rune. Such exhaustive tests are possible as the the number of
// runes in Unicode is limited.
package triegen // import "golang.org/x/text/internal/triegen"

// TODO: Arguably, the internally optimized data types would not have to be
// exposed in the generated API. We could also investigate not generating the
// code, but using it through a package. We would have to investigate the impact
// on performance of making such change, though. For packages like unicode/norm,
// small changes like this could tank performance.

import (
	"encoding/binary"
	"fmt"
	"hash/crc64"
	"io"
	"log"
	"unicode/utf8"
)

// builder builds a set of tries for associating values with runes. The set of
// tries can share common index and value blocks.
type builder struct {
	Name string

	// ValueType is the type of the trie values looked up.
	ValueType string

	// ValueSize is the byte size of the ValueType.
	ValueSize int

	// IndexType is the type of trie index values used for all UTF-8 bytes of
	// a rune except the last one.
	IndexType string

	// IndexSize is the byte size of the IndexType.
	IndexSize int

	// SourceType is used when generating the lookup functions. If the user
	// requests StringSupport, all lookup functions will be generated for
	// string input as well.
	SourceType string

	Trie []*Trie

	IndexBlocks []*node
	ValueBlocks [][]uint64
	Compactions []compaction
	Checksum    uint64

	ASCIIBlock   string
	StarterBlock string

	indexBlockIdx map[uint64]int
	valueBlockIdx map[uint64]nodeIndex
	asciiBlockIdx map[uint64]int

	// Stats are used to fill out the template.
	Stats struct {
		NValueEntries int
		NValueBytes   int
		NIndexEntries int
		NIndexBytes   int
		NHandleBytes  int
	}

	err error
}

// A nodeIndex encodes the index of a node, which is defined by the compaction
// which stores it and an index within the compaction. For internal nodes, the
// compaction is always 0.
type nodeIndex struct {
	compaction int
	index      int
}

// compaction keeps track of stats used for the compaction.
type compaction struct {
	c         Compacter
	blocks    []*node
	maxHandle uint32
	totalSize int

	// Used by template-based generator and thus exported.
	Cutoff  uint32
	Offset  uint32
	Handler string
}

func (b *builder) setError(err error) {
	if b.err == nil {
		b.err = err
	}
}

// An Option can be passed to Gen.
type Option func(b *builder) error

// Compact configures the trie generator to use the given Compacter.
func Compact(c Compacter) Option {
	return func(b *builder) error {
		b.Compactions = append(b.Compactions, compaction{
			c:       c,
			Handler: c.Handler() + "(n, b)"})
		return nil
	}
}

// Gen writes Go code for a shared trie lookup structure to w for the given
// Tries. The generated trie type will be called nameTrie. newNameTrie(x) will
// return the *nameTrie for tries[x]. A value can be looked up by using one of
// the various lookup methods defined on nameTrie. It returns the table size of
// the generated trie.
func Gen(w io.Writer, name string, tries []*Trie, opts ...Option) (sz int, err error) {
	// The index contains two dummy blocks, followed by the zero block. The zero
	// block is at offset 0x80, so that the offset for the zero block for
	// continuation bytes is 0.
	b := &builder{
		Name:        name,
		Trie:        tries,
		IndexBlocks: []*node{{}, {}, {}},
		Compactions: []compaction{{
			Handler: name + "Values[n<<6+uint32(b)]",
		}},
		// The 0 key in indexBlockIdx and valueBlockIdx is the hash of the zero
		// block.
		indexBlockIdx: map[uint64]int{0: 0},
		valueBlockIdx: map[uint64]nodeIndex{0: {}},
		asciiBlockIdx: map[uint64]int{},
	}
	b.Compactions[0].c = (*simpleCompacter)(b)

	for _, f := range opts {
		if err := f(b); err != nil {
			return 0, err
		}
	}
	b.build()
	if b.err != nil {
		return 0, b.err
	}
	if err = b.print(w); err != nil {
		return 0, err
	}
	return b.Size(), nil
}

// A Trie represents a single root node of a trie. A builder may build several
// overlapping tries at once.
type Trie struct {
	root *node

	hiddenTrie
}

// hiddenTrie contains values we want to be visible to the template generator,
// but hidden from the API documentation.
type hiddenTrie struct {
	Name         string
	Checksum     uint64
	ASCIIIndex   int
	StarterIndex int
}

// NewTrie returns a new trie root.
func NewTrie(name string) *Trie {
	return &Trie{
		&node{
			children: make([]*node, blockSize),
			values:   make([]uint64, utf8.RuneSelf),
		},
		hiddenTrie{Name: name},
	}
}

// Gen is a convenience wrapper around the Gen func passing t as the only trie
// and uses the name passed to NewTrie. It returns the size of the generated
// tables.
func (t *Trie) Gen(w io.Writer, opts ...Option) (sz int, err error) {
	return Gen(w, t.Name, []*Trie{t}, opts...)
}

// node is a node of the intermediate trie structure.
type node struct {
	// children holds this node's children. It is always of length 64.
	// A child node may be nil.
	children []*node

	// values contains the values of this node. If it is non-nil, this node is
	// either a root or leaf node:
	// For root nodes, len(values) == 128 and it maps the bytes in [0x00, 0x7F].
	// For leaf nodes, len(values) ==  64 and it maps the bytes in [0x80, 0xBF].
	values []uint64

	index nodeIndex
}

// Insert associates value with the given rune. Insert will panic if a non-zero
// value is passed for an invalid rune.
func (t *Trie) Insert(r rune, value uint64) {
	if value == 0 {
		return
	}
	s := string(r)
	if []rune(s)[0] != r && value != 0 {
		// Note: The UCD tables will always assign what amounts to a zero value
		// to a surrogate. Allowing a zero value for an illegal rune allows
		// users to iterate over [0..MaxRune] without having to explicitly
		// exclude surrogates, which would be tedious.
		panic(fmt.Sprintf("triegen: non-zero value for invalid rune %U", r))
	}
	if len(s) == 1 {
		// It is a root node value (ASCII).
		t.root.values[s[0]] = value
		return
	}

	n := t.root
	for ; len(s) > 1; s = s[1:] {
		if n.children == nil {
			n.children = make([]*node, blockSize)
		}
		p := s[0] % blockSize
		c := n.children[p]
		if c == nil {
			c = &node{}
			n.children[p] = c
		}
		if len(s) > 2 && c.values != nil {
			log.Fatalf("triegen: insert(%U): found internal node with values", r)
		}
		n = c
	}
	if n.values == nil {
		n.values = make([]uint64, blockSize)
	}
	if n.children != nil {
		log.Fatalf("triegen: insert(%U): found leaf node that also has child nodes", r)
	}
	n.values[s[0]-0x80] = value
}

// Size returns the number of bytes the generated trie will take to store. It
// needs to be exported as it is used in the templates.
func (b *builder) Size() int {
	// Index blocks.
	sz := len(b.IndexBlocks) * blockSize * b.IndexSize

	// Skip the first compaction, which represents the normal value blocks, as
	// its totalSize does not account for the ASCII blocks, which are managed
	// separately.
	sz += len(b.ValueBlocks) * blockSize * b.ValueSize
	for _, c := range b.Compactions[1:] {
		sz += c.totalSize
	}

	// TODO: this computation does not account for the fixed overhead of a using
	// a compaction, either code or data. As for data, though, the typical
	// overhead of data is in the order of bytes (2 bytes for cases). Further,
	// the savings of using a compaction should anyway be substantial for it to
	// be worth it.

	// For multi-root tries, we also need to account for the handles.
	if len(b.Trie) > 1 {
		sz += 2 * b.IndexSize * len(b.Trie)
	}
	return sz
}

func (b *builder) build() {
	// Compute the sizes of the values.
	var vmax uint64
	for _, t := range b.Trie {
		vmax = maxValue(t.root, vmax)
	}
	b.ValueType, b.ValueSize = getIntType(vmax)

	// Compute all block allocations.
	// TODO: first compute the ASCII blocks for all tries and then the other
	// nodes. ASCII blocks are more restricted in placement, as they require two
	// blocks to be placed consecutively. Processing them first may improve
	// sharing (at least one zero block can be expected to be saved.)
	for _, t := range b.Trie {
		b.Checksum += b.buildTrie(t)
	}

	// Compute the offsets for all the Compacters.
	offset := uint32(0)
	for i := range b.Compactions {
		c := &b.Compactions[i]
		c.Offset = offset
		offset += c.maxHandle + 1
		c.Cutoff = offset
	}

	// Compute the sizes of indexes.
	// TODO: different byte positions could have different sizes. So far we have
	// not found a case where this is beneficial.
	imax := uint64(b.Compactions[len(b.Compactions)-1].Cutoff)
	for _, ib := range b.IndexBlocks {
		if x := uint64(ib.index.index); x > imax {
			imax = x
		}
	}
	b.IndexType, b.IndexSize = getIntType(imax)
}

func maxValue(n *node, max uint64) uint64 {
	if n == nil {
		return max
	}
	for _, c := range n.children {
		max = maxValue(c, max)
	}
	for _, v := range n.values {
		if max < v {
			max = v
		}
	}
	return max
}

func getIntType(v uint64) (string, int) {
	switch {
	case v < 1<<8:
		return "uint8", 1
	case v < 1<<16:
		return "uint16", 2
	case v < 1<<32:
		return "uint32", 4
	}
	return "uint64", 8
}

const (
	blockSize = 64

	// Subtract two blocks to offset 0x80, the first continuation byte.
	blockOffset = 2

	// Subtract three blocks to offset 0xC0, the first non-ASCII starter.
	rootBlockOffset = 3
)

var crcTable = crc64.MakeTable(crc64.ISO)

func (b *builder) buildTrie(t *Trie) uint64 {
	n := t.root

	// Get the ASCII offset. For the first trie, the ASCII block will be at
	// position 0.
	hasher := crc64.New(crcTable)
	binary.Write(hasher, binary.BigEndian, n.values)
	hash := hasher.Sum64()

	v, ok := b.asciiBlockIdx[hash]
	if !ok {
		v = len(b.ValueBlocks)
		b.asciiBlockIdx[hash] = v

		b.ValueBlocks = append(b.ValueBlocks, n.values[:blockSize], n.values[blockSize:])
		if v == 0 {
			// Add the zero block at position 2 so that it will be assigned a
			// zero reference in the lookup blocks.
			// TODO: always do this? This would allow us to remove a check from
			// the trie lookup, but at the expense of extra space. Analyze
			// performance for unicode/norm.
			b.ValueBlocks = append(b.ValueBlocks, make([]uint64, blockSize))
		}
	}
	t.ASCIIIndex = v

	// Compute remaining offsets.
	t.Checksum = b.computeOffsets(n, true)
	// We already subtracted the normal blockOffset from the index. Subtract the
	// difference for starter bytes.
	t.StarterIndex = n.index.index - (rootBlockOffset - blockOffset)
	return t.Checksum
}

func (b *builder) computeOffsets(n *node, root bool) uint64 {
	// For the first trie, the root lookup block will be at position 3, which is
	// the offset for UTF-8 non-ASCII starter bytes.
	first := len(b.IndexBlocks) == rootBlockOffset
	if first {
		b.IndexBlocks = append(b.IndexBlocks, n)
	}

	// We special-case the cases where all values recursively are 0. This allows
	// for the use of a zero block to which all such values can be directed.
	hash := uint64(0)
	if n.children != nil || n.values != nil {
		hasher := crc64.New(crcTable)
		for _, c := range n.children {
			var v uint64
			if c != nil {
				v = b.computeOffsets(c, false)
			}
			binary.Write(hasher, binary.BigEndian, v)
		}
		binary.Write(hasher, binary.BigEndian, n.values)
		hash = hasher.Sum64()
	}

	if first {
		b.indexBlockIdx[hash] = rootBlockOffset - blockOffset
	}

	// Compacters don't apply to internal nodes.
	if n.children != nil {
		v, ok := b.indexBlockIdx[hash]
		if !ok {
			v = len(b.IndexBlocks) - blockOffset
			b.IndexBlocks = append(b.IndexBlocks, n)
			b.indexBlockIdx[hash] = v
		}
		n.index = nodeIndex{0, v}
	} else {
		h, ok := b.valueBlockIdx[hash]
		if !ok {
			bestI, bestSize := 0, blockSize*b.ValueSize
			for i, c := range b.Compactions[1:] {
				if sz, ok := c.c.Size(n.values); ok && bestSize > sz {
					bestI, bestSize = i+1, sz
				}
			}
			c := &b.Compactions[bestI]
			c.totalSize += bestSize
			v := c.c.Store(n.values)
			if c.maxHandle < v {
				c.maxHandle = v
			}
			h = nodeIndex{bestI, int(v)}
			b.valueBlockIdx[hash] = h
		}
		n.index = h
	}
	return hash
}
