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

// Tag 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
}
