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

//go:generate go run maketables.go -output tables.go

// Package display provides display names for languages, scripts and regions in
// a requested language.
//
// The data is based on CLDR's localeDisplayNames. It includes the names of the
// draft level "contributed" or "approved". The resulting tables are quite
// large. The display package is designed so that users can reduce the linked-in
// table sizes by cherry picking the languages one wishes to support. There is a
// Dictionary defined for a selected set of common languages for this purpose.
package display // import "golang.org/x/text/language/display"

import (
	"fmt"
	"strings"

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

/*
TODO:
All fairly low priority at the moment:
  - Include alternative and variants as an option (using func options).
  - Option for returning the empty string for undefined values.
  - Support variants, currencies, time zones, option names and other data
    provided in CLDR.
  - Do various optimizations:
    - Reduce size of offset tables.
    - Consider compressing infrequently used languages and decompress on demand.
*/

// A Formatter formats a tag in the current language. It is used in conjunction
// with the message package.
type Formatter struct {
	lookup func(tag int, x interface{}) string
	x      interface{}
}

// Format implements "golang.org/x/text/internal/format".Formatter.
func (f Formatter) Format(state format.State, verb rune) {
	// TODO: there are a lot of inefficiencies in this code. Fix it when we
	// language.Tag has embedded compact tags.
	t := state.Language()
	_, index, _ := matcher.Match(t)
	str := f.lookup(index, f.x)
	if str == "" {
		// TODO: use language-specific punctuation.
		// TODO: use codePattern instead of language?
		if unknown := f.lookup(index, language.Und); unknown != "" {
			fmt.Fprintf(state, "%v (%v)", unknown, f.x)
		} else {
			fmt.Fprintf(state, "[language: %v]", f.x)
		}
	} else {
		state.Write([]byte(str))
	}
}

// Language returns a Formatter that renders the name for lang in the
// the current language. x may be a language.Base or a language.Tag.
// It renders lang in the default language if no translation for the current
// language is supported.
func Language(lang interface{}) Formatter {
	return Formatter{langFunc, lang}
}

// Region returns a Formatter that renders the name for region in the current
// language. region may be a language.Region or a language.Tag.
// It renders region in the default language if no translation for the current
// language is supported.
func Region(region interface{}) Formatter {
	return Formatter{regionFunc, region}
}

// Script returns a Formatter that renders the name for script in the current
// language. script may be a language.Script or a language.Tag.
// It renders script in the default language if no translation for the current
// language is supported.
func Script(script interface{}) Formatter {
	return Formatter{scriptFunc, script}
}

// Script returns a Formatter that renders the name for tag in the current
// language. tag may be a language.Tag.
// It renders tag in the default language if no translation for the current
// language is supported.
func Tag(tag interface{}) Formatter {
	return Formatter{tagFunc, tag}
}

// A Namer is used to get the name for a given value, such as a Tag, Language,
// Script or Region.
type Namer interface {
	// Name returns a display string for the given value. A Namer returns an
	// empty string for values it does not support. A Namer may support naming
	// an unspecified value. For example, when getting the name for a region for
	// a tag that does not have a defined Region, it may return the name for an
	// unknown region. It is up to the user to filter calls to Name for values
	// for which one does not want to have a name string.
	Name(x interface{}) string
}

var (
	// Supported lists the languages for which names are defined.
	Supported language.Coverage

	// The set of all possible values for which names are defined. Note that not
	// all Namer implementations will cover all the values of a given type.
	// A Namer will return the empty string for unsupported values.
	Values language.Coverage

	matcher language.Matcher
)

func init() {
	tags := make([]language.Tag, numSupported)
	s := supported
	for i := range tags {
		p := strings.IndexByte(s, '|')
		tags[i] = language.Raw.Make(s[:p])
		s = s[p+1:]
	}
	matcher = language.NewMatcher(tags)
	Supported = language.NewCoverage(tags)

	Values = language.NewCoverage(langTagSet.Tags, supportedScripts, supportedRegions)
}

// Languages returns a Namer for naming languages. It returns nil if there is no
// data for the given tag. The type passed to Name must be either language.Base
// or language.Tag. Note that the result may differ between passing a tag or its
// base language. For example, for English, passing "nl-BE" would return Flemish
// whereas passing "nl" returns "Dutch".
func Languages(t language.Tag) Namer {
	if _, index, conf := matcher.Match(t); conf != language.No {
		return languageNamer(index)
	}
	return nil
}

type languageNamer int

func langFunc(i int, x interface{}) string {
	return nameLanguage(languageNamer(i), x)
}

func (n languageNamer) name(i int) string {
	return lookup(langHeaders[:], int(n), i)
}

// Name implements the Namer interface for language names.
func (n languageNamer) Name(x interface{}) string {
	return nameLanguage(n, x)
}

// nonEmptyIndex walks up the parent chain until a non-empty header is found.
// It returns -1 if no index could be found.
func nonEmptyIndex(h []header, index int) int {
	for ; index != -1 && h[index].data == ""; index = int(parents[index]) {
	}
	return index
}

// Scripts returns a Namer for naming scripts. It returns nil if there is no
// data for the given tag. The type passed to Name must be either a
// language.Script or a language.Tag. It will not attempt to infer a script for
// tags with an unspecified script.
func Scripts(t language.Tag) Namer {
	if _, index, conf := matcher.Match(t); conf != language.No {
		if index = nonEmptyIndex(scriptHeaders[:], index); index != -1 {
			return scriptNamer(index)
		}
	}
	return nil
}

type scriptNamer int

func scriptFunc(i int, x interface{}) string {
	return nameScript(scriptNamer(i), x)
}

func (n scriptNamer) name(i int) string {
	return lookup(scriptHeaders[:], int(n), i)
}

// Name implements the Namer interface for script names.
func (n scriptNamer) Name(x interface{}) string {
	return nameScript(n, x)
}

// Regions returns a Namer for naming regions. It returns nil if there is no
// data for the given tag. The type passed to Name must be either a
// language.Region or a language.Tag. It will not attempt to infer a region for
// tags with an unspecified region.
func Regions(t language.Tag) Namer {
	if _, index, conf := matcher.Match(t); conf != language.No {
		if index = nonEmptyIndex(regionHeaders[:], index); index != -1 {
			return regionNamer(index)
		}
	}
	return nil
}

type regionNamer int

func regionFunc(i int, x interface{}) string {
	return nameRegion(regionNamer(i), x)
}

func (n regionNamer) name(i int) string {
	return lookup(regionHeaders[:], int(n), i)
}

// Name implements the Namer interface for region names.
func (n regionNamer) Name(x interface{}) string {
	return nameRegion(n, x)
}

// Tags returns a Namer for giving a full description of a tag. The names of
// scripts and regions that are not already implied by the language name will
// in appended within parentheses. It returns nil if there is not data for the
// given tag. The type passed to Name must be a tag.
func Tags(t language.Tag) Namer {
	if _, index, conf := matcher.Match(t); conf != language.No {
		return tagNamer(index)
	}
	return nil
}

type tagNamer int

func tagFunc(i int, x interface{}) string {
	return nameTag(languageNamer(i), scriptNamer(i), regionNamer(i), x)
}

// Name implements the Namer interface for tag names.
func (n tagNamer) Name(x interface{}) string {
	return nameTag(languageNamer(n), scriptNamer(n), regionNamer(n), x)
}

// lookup finds the name for an entry in a global table, traversing the
// inheritance hierarchy if needed.
func lookup(table []header, dict, want int) string {
	for dict != -1 {
		if s := table[dict].name(want); s != "" {
			return s
		}
		dict = int(parents[dict])
	}
	return ""
}

// A Dictionary holds a collection of Namers for a single language. One can
// reduce the amount of data linked in to a binary by only referencing
// Dictionaries for the languages one needs to support instead of using the
// generic Namer factories.
type Dictionary struct {
	parent *Dictionary
	lang   header
	script header
	region header
}

// Tags returns a Namer for giving a full description of a tag. The names of
// scripts and regions that are not already implied by the language name will
// in appended within parentheses. It returns nil if there is not data for the
// given tag. The type passed to Name must be a tag.
func (d *Dictionary) Tags() Namer {
	return dictTags{d}
}

type dictTags struct {
	d *Dictionary
}

// Name implements the Namer interface for tag names.
func (n dictTags) Name(x interface{}) string {
	return nameTag(dictLanguages{n.d}, dictScripts{n.d}, dictRegions{n.d}, x)
}

// Languages returns a Namer for naming languages. It returns nil if there is no
// data for the given tag. The type passed to Name must be either language.Base
// or language.Tag. Note that the result may differ between passing a tag or its
// base language. For example, for English, passing "nl-BE" would return Flemish
// whereas passing "nl" returns "Dutch".
func (d *Dictionary) Languages() Namer {
	return dictLanguages{d}
}

type dictLanguages struct {
	d *Dictionary
}

func (n dictLanguages) name(i int) string {
	for d := n.d; d != nil; d = d.parent {
		if s := d.lang.name(i); s != "" {
			return s
		}
	}
	return ""
}

// Name implements the Namer interface for language names.
func (n dictLanguages) Name(x interface{}) string {
	return nameLanguage(n, x)
}

// Scripts returns a Namer for naming scripts. It returns nil if there is no
// data for the given tag. The type passed to Name must be either a
// language.Script or a language.Tag. It will not attempt to infer a script for
// tags with an unspecified script.
func (d *Dictionary) Scripts() Namer {
	return dictScripts{d}
}

type dictScripts struct {
	d *Dictionary
}

func (n dictScripts) name(i int) string {
	for d := n.d; d != nil; d = d.parent {
		if s := d.script.name(i); s != "" {
			return s
		}
	}
	return ""
}

// Name implements the Namer interface for script names.
func (n dictScripts) Name(x interface{}) string {
	return nameScript(n, x)
}

// Regions returns a Namer for naming regions. It returns nil if there is no
// data for the given tag. The type passed to Name must be either a
// language.Region or a language.Tag. It will not attempt to infer a region for
// tags with an unspecified region.
func (d *Dictionary) Regions() Namer {
	return dictRegions{d}
}

type dictRegions struct {
	d *Dictionary
}

func (n dictRegions) name(i int) string {
	for d := n.d; d != nil; d = d.parent {
		if s := d.region.name(i); s != "" {
			return s
		}
	}
	return ""
}

// Name implements the Namer interface for region names.
func (n dictRegions) Name(x interface{}) string {
	return nameRegion(n, x)
}

// A SelfNamer implements a Namer that returns the name of language in this same
// language. It provides a very compact mechanism to provide a comprehensive
// list of languages to users in their native language.
type SelfNamer struct {
	// Supported defines the values supported by this Namer.
	Supported language.Coverage
}

var (
	// Self is a shared instance of a SelfNamer.
	Self *SelfNamer = &self

	self = SelfNamer{language.NewCoverage(selfTagSet.Tags)}
)

// Name returns the name of a given language tag in the language identified by
// this tag. It supports both the language.Base and language.Tag types.
func (n SelfNamer) Name(x interface{}) string {
	t, _ := language.All.Compose(x)
	base, scr, reg := t.Raw()
	baseScript := language.Script{}
	if (scr == language.Script{} && reg != language.Region{}) {
		// For looking up in the self dictionary, we need to select the
		// maximized script. This is even the case if the script isn't
		// specified.
		s1, _ := t.Script()
		if baseScript = getScript(base); baseScript != s1 {
			scr = s1
		}
	}

	i, scr, reg := selfTagSet.index(base, scr, reg)
	if i == -1 {
		return ""
	}

	// Only return the display name if the script matches the expected script.
	if (scr != language.Script{}) {
		if (baseScript == language.Script{}) {
			baseScript = getScript(base)
		}
		if baseScript != scr {
			return ""
		}
	}

	return selfHeaders[0].name(i)
}

// getScript returns the maximized script for a base language.
func getScript(b language.Base) language.Script {
	tag, _ := language.Raw.Compose(b)
	scr, _ := tag.Script()
	return scr
}
