// Copyright 2017 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 cldrtree builds and generates a CLDR index file, including all
// inheritance.
package cldrtree

//go:generate go test -gen

// cldrtree stores CLDR data in a tree-like structure called Tree. In the CLDR
// data each branch in the tree is indicated by either an element name or an
// attribute value. A Tree does not distinguish between these two cases, but
// rather assumes that all branches can be accessed by an enum with a compact
// range of positive integer values starting from 0.
//
// Each Tree consists of three parts:
//    - a slice mapping compact language identifiers to an offset into a set of
//      indices,
//    - a set of indices, stored as a large blob of uint16 values that encode
//      the actual tree structure of data, and
//    - a set of buckets that each holds a collection of strings.
// each of which is explained in more detail below.
//
//
// Tree lookup
// A tree lookup is done by providing a locale and a "path", which is a
// sequence of enum values. The search starts with getting the index for the
// given locale and then incrementally jumping into the index using the path
// values. If an element cannot be found in the index, the search starts anew
// for the locale's parent locale. The path may change during lookup by means
// of aliasing, described below.
//
// Buckets
// Buckets hold the actual string data of the leaf values of the CLDR tree.
// This data is stored in buckets, rather than one large string, for multiple
// reasons:
//   - it allows representing leaf values more compactly, by storing all leaf
//     values in a single bucket and then needing only needing a uint16 to index
//     into this bucket for all leaf values,
//   - (TBD) allow multiple trees to share subsets of buckets, mostly to allow
//     linking in a smaller amount of data if only a subset of the buckets is
//     needed,
//   - to be nice to go fmt and the compiler.
//
// indices
// An index is a slice of uint16 for which the values are interpreted in one of
// two ways: as a node or a set of leaf values.
// A set of leaf values has the following form:
//      <max_size>, <bucket>, <offset>...
// max_size indicates the maximum enum value for which an offset is defined.
// An offset value of 0xFFFF (missingValue) also indicates an undefined value.
// If defined offset indicates the offset within the given bucket of the string.
// A node value has the following form:
//      <max_size>, <offset_or_alias>...
// max_size indicates the maximum value for which an offset is defined.
// A missing offset may also be indicated with 0. If the high bit (0x8000, or
// inheritMask) is not set, the offset points to the offset within the index
// for the current locale.
// An offset with high bit set is an alias. In this case the uint16 has the form
//       bits:
//         15: 1
//      14-12: negative offset into path relative to current position
//       0-11: new enum value for path element.
// On encountering an alias, the path is modified accordingly and the lookup is
// restarted for the given locale.

import (
	"fmt"
	"reflect"
	"regexp"
	"strings"
	"unicode/utf8"

	"golang.org/x/text/internal/gen"
	"golang.org/x/text/language"
	"golang.org/x/text/unicode/cldr"
)

// TODO:
// - allow two Trees to share the same set of buckets.

// A Builder allows storing CLDR data in compact form.
type Builder struct {
	table []string

	rootMeta    *metaData
	locales     []locale
	strToBucket map[string]stringInfo
	buckets     [][]byte
	enums       []*enum
	err         error

	// Stats
	size        int
	sizeAll     int
	bucketWaste int
}

const (
	maxBucketSize = 8 * 1024 // 8K
	maxStrlen     = 254      // allow 0xFF sentinel
)

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

func (b *Builder) addString(data string) stringInfo {
	data = b.makeString(data)
	info, ok := b.strToBucket[data]
	if !ok {
		b.size += len(data)
		x := len(b.buckets) - 1
		bucket := b.buckets[x]
		if len(bucket)+len(data) < maxBucketSize {
			info.bucket = uint16(x)
			info.bucketPos = uint16(len(bucket))
			b.buckets[x] = append(bucket, data...)
		} else {
			info.bucket = uint16(len(b.buckets))
			info.bucketPos = 0
			b.buckets = append(b.buckets, []byte(data))
		}
		b.strToBucket[data] = info
	}
	return info
}

func (b *Builder) addStringToBucket(data string, bucket uint16) stringInfo {
	data = b.makeString(data)
	info, ok := b.strToBucket[data]
	if !ok || info.bucket != bucket {
		if ok {
			b.bucketWaste += len(data)
		}
		b.size += len(data)
		bk := b.buckets[bucket]
		info.bucket = bucket
		info.bucketPos = uint16(len(bk))
		b.buckets[bucket] = append(bk, data...)
		b.strToBucket[data] = info
	}
	return info
}

func (b *Builder) makeString(data string) string {
	if len(data) > maxStrlen {
		b.setError(fmt.Errorf("string %q exceeds maximum length of %d", data, maxStrlen))
		data = data[:maxStrlen]
		for i := len(data) - 1; i > len(data)-4; i-- {
			if utf8.RuneStart(data[i]) {
				data = data[:i]
				break
			}
		}
	}
	data = string([]byte{byte(len(data))}) + data
	b.sizeAll += len(data)
	return data
}

type stringInfo struct {
	bufferPos uint32
	bucket    uint16
	bucketPos uint16
}

// New creates a new Builder.
func New(tableName string) *Builder {
	b := &Builder{
		strToBucket: map[string]stringInfo{},
		buckets:     [][]byte{nil}, // initialize with first bucket.
	}
	b.rootMeta = &metaData{
		b:        b,
		typeInfo: &typeInfo{},
	}
	return b
}

// Gen writes all the tables and types for the collected data.
func (b *Builder) Gen(w *gen.CodeWriter) error {
	t, err := build(b)
	if err != nil {
		return err
	}
	return generate(b, t, w)
}

// GenTestData generates tables useful for testing data generated with Gen.
func (b *Builder) GenTestData(w *gen.CodeWriter) error {
	return generateTestData(b, w)
}

type locale struct {
	tag  language.Tag
	root *Index
}

// Locale creates an index for the given locale.
func (b *Builder) Locale(t language.Tag) *Index {
	index := &Index{
		meta: b.rootMeta,
	}
	b.locales = append(b.locales, locale{tag: t, root: index})
	return index
}

// An Index holds a map of either leaf values or other indices.
type Index struct {
	meta *metaData

	subIndex []*Index
	values   []keyValue
}

func (i *Index) setError(err error) { i.meta.b.setError(err) }

type keyValue struct {
	key   enumIndex
	value stringInfo
}

// Element is a CLDR XML element.
type Element interface {
	GetCommon() *cldr.Common
}

// Index creates a subindex where the type and enum values are not shared
// with siblings by default. The name is derived from the elem. If elem is
// an alias reference, the alias will be resolved and linked. If elem is nil
// Index returns nil.
func (i *Index) Index(elem Element, opt ...Option) *Index {
	if elem == nil || reflect.ValueOf(elem).IsNil() {
		return nil
	}
	c := elem.GetCommon()
	o := &options{
		parent: i,
		name:   c.GetCommon().Element(),
	}
	o.fill(opt)
	o.setAlias(elem)
	return i.subIndexForKey(o)
}

// IndexWithName is like Section but derives the name from the given name.
func (i *Index) IndexWithName(name string, opt ...Option) *Index {
	o := &options{parent: i, name: name}
	o.fill(opt)
	return i.subIndexForKey(o)
}

// IndexFromType creates a subindex the value of tye type attribute as key. It
// will also configure the Index to share the enumeration values with all
// sibling values. If elem is an alias, it will be resolved and linked.
func (i *Index) IndexFromType(elem Element, opts ...Option) *Index {
	o := &options{
		parent: i,
		name:   elem.GetCommon().Type,
	}
	o.fill(opts)
	o.setAlias(elem)
	useSharedType()(o)
	return i.subIndexForKey(o)
}

// IndexFromAlt creates a subindex the value of tye alt attribute as key. It
// will also configure the Index to share the enumeration values with all
// sibling values. If elem is an alias, it will be resolved and linked.
func (i *Index) IndexFromAlt(elem Element, opts ...Option) *Index {
	o := &options{
		parent: i,
		name:   elem.GetCommon().Alt,
	}
	o.fill(opts)
	o.setAlias(elem)
	useSharedType()(o)
	return i.subIndexForKey(o)
}

func (i *Index) subIndexForKey(opts *options) *Index {
	key := opts.name
	if len(i.values) > 0 {
		panic(fmt.Errorf("cldrtree: adding Index for %q when value already exists", key))
	}
	meta := i.meta.sub(key, opts)
	for _, x := range i.subIndex {
		if x.meta == meta {
			return x
		}
	}
	if alias := opts.alias; alias != nil {
		if a := alias.GetCommon().Alias; a != nil {
			if a.Source != "locale" {
				i.setError(fmt.Errorf("cldrtree: non-locale alias not supported %v", a.Path))
			}
			if meta.inheritOffset < 0 {
				i.setError(fmt.Errorf("cldrtree: alias was already set %v", a.Path))
			}
			path := a.Path
			for ; strings.HasPrefix(path, "../"); path = path[len("../"):] {
				meta.inheritOffset--
			}
			m := aliasRe.FindStringSubmatch(path)
			if m == nil {
				i.setError(fmt.Errorf("cldrtree: could not parse alias %q", a.Path))
			} else {
				key := m[4]
				if key == "" {
					key = m[1]
				}
				meta.inheritIndex = key
			}
		}
	}
	x := &Index{meta: meta}
	i.subIndex = append(i.subIndex, x)
	return x
}

var aliasRe = regexp.MustCompile(`^([a-zA-Z]+)(\[@([a-zA-Z-]+)='([a-zA-Z-]+)'\])?`)

// SetValue sets the value, the data from a CLDR XML element, for the given key.
func (i *Index) SetValue(key string, value Element, opt ...Option) {
	if len(i.subIndex) > 0 {
		panic(fmt.Errorf("adding value for key %q when index already exists", key))
	}
	o := &options{parent: i}
	o.fill(opt)
	c := value.GetCommon()
	if c.Alias != nil {
		i.setError(fmt.Errorf("cldrtree: alias not supported for SetValue %v", c.Alias.Path))
	}
	i.setValue(key, c.Data(), o)
}

func (i *Index) setValue(key, data string, o *options) {
	index, _ := i.meta.typeInfo.lookupSubtype(key, o)
	kv := keyValue{key: index}
	if len(i.values) > 0 {
		// Add string to the same bucket as the other values.
		bucket := i.values[0].value.bucket
		kv.value = i.meta.b.addStringToBucket(data, bucket)
	} else {
		kv.value = i.meta.b.addString(data)
	}
	i.values = append(i.values, kv)
}
