// Copyright 2013 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.

//go:generate go run gen.go gen_index.go -output tables.go

package compact

// TODO: Remove above NOTE after:
// - verifying that tables are dropped correctly (most notably matcher tables).

import (
	"strings"

	"golang.org/x/text/internal/language"
)

// Tag represents a BCP 47 language tag. It is used to specify an instance of a
// specific language or locale. All language tag values are guaranteed to be
// well-formed.
type Tag struct {
	language ID
	locale   ID
	full     fullTag // always a language.Tag for now.
}

const _und = 0

type fullTag interface {
	IsRoot() bool
	Parent() language.Tag
}

// Make a compact Tag from a fully specified internal language Tag.
func Make(t language.Tag) (tag Tag) {
	if region := t.TypeForKey("rg"); len(region) == 6 && region[2:] == "zzzz" {
		if r, err := language.ParseRegion(region[:2]); err == nil {
			tFull := t
			t, _ = t.SetTypeForKey("rg", "")
			// TODO: should we not consider "va" for the language tag?
			var exact1, exact2 bool
			tag.language, exact1 = FromTag(t)
			t.RegionID = r
			tag.locale, exact2 = FromTag(t)
			if !exact1 || !exact2 {
				tag.full = tFull
			}
			return tag
		}
	}
	lang, ok := FromTag(t)
	tag.language = lang
	tag.locale = lang
	if !ok {
		tag.full = t
	}
	return tag
}

// Tag returns an internal language Tag version of this tag.
func (t Tag) Tag() language.Tag {
	if t.full != nil {
		return t.full.(language.Tag)
	}
	tag := t.language.Tag()
	if t.language != t.locale {
		loc := t.locale.Tag()
		tag, _ = tag.SetTypeForKey("rg", strings.ToLower(loc.RegionID.String())+"zzzz")
	}
	return tag
}

// IsCompact reports whether this tag is fully defined in terms of ID.
func (t *Tag) IsCompact() bool {
	return t.full == nil
}

// MayHaveVariants reports whether a tag may have variants. If it returns false
// it is guaranteed the tag does not have variants.
func (t Tag) MayHaveVariants() bool {
	return t.full != nil || int(t.language) >= len(coreTags)
}

// MayHaveExtensions reports whether a tag may have extensions. If it returns
// false it is guaranteed the tag does not have them.
func (t Tag) MayHaveExtensions() bool {
	return t.full != nil ||
		int(t.language) >= len(coreTags) ||
		t.language != t.locale
}

// IsRoot returns true if t is equal to language "und".
func (t Tag) IsRoot() bool {
	if t.full != nil {
		return t.full.IsRoot()
	}
	return t.language == _und
}

// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a
// specific language are substituted with fields from the parent language.
// The parent for a language may change for newer versions of CLDR.
func (t Tag) Parent() Tag {
	if t.full != nil {
		return Make(t.full.Parent())
	}
	if t.language != t.locale {
		// Simulate stripping -u-rg-xxxxxx
		return Tag{language: t.language, locale: t.language}
	}
	// TODO: use parent lookup table once cycle from internal package is
	// removed. Probably by internalizing the table and declaring this fast
	// enough.
	// lang := compactID(internal.Parent(uint16(t.language)))
	lang, _ := FromTag(t.language.Tag().Parent())
	return Tag{language: lang, locale: lang}
}

// returns token t and the rest of the string.
func nextToken(s string) (t, tail string) {
	p := strings.Index(s[1:], "-")
	if p == -1 {
		return s[1:], ""
	}
	p++
	return s[1:p], s[p:]
}

// LanguageID returns an index, where 0 <= index < NumCompactTags, for tags
// for which data exists in the text repository.The index will change over time
// and should not be stored in persistent storage. If t does not match a compact
// index, exact will be false and the compact index will be returned for the
// first match after repeatedly taking the Parent of t.
func LanguageID(t Tag) (id ID, exact bool) {
	return t.language, t.full == nil
}

// TODO: make these functions and methods public once we settle on the API and
//

// RegionalID returns the ID for the regional variant of this tag. This index is
// used to indicate region-specific overrides, such as default currency, default
// calendar and week data, default time cycle, and default measurement system
// and unit preferences.
//
// For instance, the tag en-GB-u-rg-uszzzz specifies British English with US
// settings for currency, number formatting, etc. The CompactIndex for this tag
// will be that for en-GB, while the RegionalID will be the one corresponding to
// en-US.
func RegionalID(t Tag) (id ID, exact bool) {
	return t.locale, t.full == nil
}

// LanguageTag returns t stripped of regional variant indicators.
//
// At the moment this means it is stripped of a regional and variant subtag "rg"
// and "va" in the "u" extension.
func (t Tag) LanguageTag() Tag {
	if t.full == nil {
		return Tag{language: t.language, locale: t.language}
	}
	tt := t.Tag()
	tt.SetTypeForKey("rg", "")
	tt.SetTypeForKey("va", "")
	return Make(tt)
}

// RegionalTag returns the regional variant of the tag.
//
// At the moment this means that the region is set from the regional subtag
// "rg" in the "u" extension.
func (t Tag) RegionalTag() Tag {
	rt := Tag{language: t.locale, locale: t.locale}
	if t.full == nil {
		return rt
	}
	b := language.Builder{}
	tag := t.Tag()
	// tag, _ = tag.SetTypeForKey("rg", "")
	b.SetTag(t.locale.Tag())
	if v := tag.Variants(); v != "" {
		for _, v := range strings.Split(v, "-") {
			b.AddVariant(v)
		}
	}
	for _, e := range tag.Extensions() {
		b.AddExt(e)
	}
	return t
}

// FromTag reports closest matching ID for an internal language Tag.
func FromTag(t language.Tag) (id ID, exact bool) {
	// TODO: perhaps give more frequent tags a lower index.
	// TODO: we could make the indexes stable. This will excluded some
	//       possibilities for optimization, so don't do this quite yet.
	exact = true

	b, s, r := t.Raw()
	if t.HasString() {
		if t.IsPrivateUse() {
			// We have no entries for user-defined tags.
			return 0, false
		}
		hasExtra := false
		if t.HasVariants() {
			if t.HasExtensions() {
				build := language.Builder{}
				build.SetTag(language.Tag{LangID: b, ScriptID: s, RegionID: r})
				build.AddVariant(t.Variants())
				exact = false
				t = build.Make()
			}
			hasExtra = true
		} else if _, ok := t.Extension('u'); ok {
			// TODO: va may mean something else. Consider not considering it.
			// Strip all but the 'va' entry.
			old := t
			variant := t.TypeForKey("va")
			t = language.Tag{LangID: b, ScriptID: s, RegionID: r}
			if variant != "" {
				t, _ = t.SetTypeForKey("va", variant)
				hasExtra = true
			}
			exact = old == t
		} else {
			exact = false
		}
		if hasExtra {
			// We have some variants.
			for i, s := range specialTags {
				if s == t {
					return ID(i + len(coreTags)), exact
				}
			}
			exact = false
		}
	}
	if x, ok := getCoreIndex(t); ok {
		return x, exact
	}
	exact = false
	if r != 0 && s == 0 {
		// Deal with cases where an extra script is inserted for the region.
		t, _ := t.Maximize()
		if x, ok := getCoreIndex(t); ok {
			return x, exact
		}
	}
	for t = t.Parent(); t != root; t = t.Parent() {
		// No variants specified: just compare core components.
		// The key has the form lllssrrr, where l, s, and r are nibbles for
		// respectively the langID, scriptID, and regionID.
		if x, ok := getCoreIndex(t); ok {
			return x, exact
		}
	}
	return 0, exact
}

var root = language.Tag{}
