// 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 catalog defines collections of translated format strings.
//
// This package mostly defines types for populating catalogs with messages. The
// catmsg package contains further definitions for creating custom message and
// dictionary types as well as packages that use Catalogs.
//
// Package catalog defines various interfaces: Dictionary, Loader, and Message.
// A Dictionary maintains a set of translations of format strings for a single
// language. The Loader interface defines a source of dictionaries. A
// translation of a format string is represented by a Message.
//
// # Catalogs
//
// A Catalog defines a programmatic interface for setting message translations.
// It maintains a set of per-language dictionaries with translations for a set
// of keys. For message translation to function properly, a translation should
// be defined for each key for each supported language. A dictionary may be
// underspecified, though, if there is a parent language that already defines
// the key. For example, a Dictionary for "en-GB" could leave out entries that
// are identical to those in a dictionary for "en".
//
// # Messages
//
// A Message is a format string which varies on the value of substitution
// variables. For instance, to indicate the number of results one could want "no
// results" if there are none, "1 result" if there is 1, and "%d results" for
// any other number. Catalog is agnostic to the kind of format strings that are
// used: for instance, messages can follow either the printf-style substitution
// from package fmt or use templates.
//
// A Message does not substitute arguments in the format string. This job is
// reserved for packages that render strings, such as message, that use Catalogs
// to selected string. This separation of concerns allows Catalog to be used to
// store any kind of formatting strings.
//
// # Selecting messages based on linguistic features of substitution arguments
//
// Messages may vary based on any linguistic features of the argument values.
// The most common one is plural form, but others exist.
//
// Selection messages are provided in packages that provide support for a
// specific linguistic feature. The following snippet uses plural.Selectf:
//
//	catalog.Set(language.English, "You are %d minute(s) late.",
//		plural.Selectf(1, "",
//			plural.One, "You are 1 minute late.",
//			plural.Other, "You are %d minutes late."))
//
// In this example, a message is stored in the Catalog where one of two messages
// is selected based on the first argument, a number. The first message is
// selected if the argument is singular (identified by the selector "one") and
// the second message is selected in all other cases. The selectors are defined
// by the plural rules defined in CLDR. The selector "other" is special and will
// always match. Each language always defines one of the linguistic categories
// to be "other." For English, singular is "one" and plural is "other".
//
// Selects can be nested. This allows selecting sentences based on features of
// multiple arguments or multiple linguistic properties of a single argument.
//
// # String interpolation
//
// There is often a lot of commonality between the possible variants of a
// message. For instance, in the example above the word "minute" varies based on
// the plural catogory of the argument, but the rest of the sentence is
// identical. Using interpolation the above message can be rewritten as:
//
//	catalog.Set(language.English, "You are %d minute(s) late.",
//		catalog.Var("minutes",
//			plural.Selectf(1, "", plural.One, "minute", plural.Other, "minutes")),
//		catalog.String("You are %[1]d ${minutes} late."))
//
// Var is defined to return the variable name if the message does not yield a
// match. This allows us to further simplify this snippet to
//
//	catalog.Set(language.English, "You are %d minute(s) late.",
//		catalog.Var("minutes", plural.Selectf(1, "", plural.One, "minute")),
//		catalog.String("You are %d ${minutes} late."))
//
// Overall this is still only a minor improvement, but things can get a lot more
// unwieldy if more than one linguistic feature is used to determine a message
// variant. Consider the following example:
//
//	// argument 1: list of hosts, argument 2: list of guests
//	catalog.Set(language.English, "%[1]v invite(s) %[2]v to their party.",
//		catalog.Var("their",
//			plural.Selectf(1, ""
//				plural.One, gender.Select(1, "female", "her", "other", "his"))),
//		catalog.Var("invites", plural.Selectf(1, "", plural.One, "invite"))
//		catalog.String("%[1]v ${invites} %[2]v to ${their} party.")),
//
// Without variable substitution, this would have to be written as
//
//	// argument 1: list of hosts, argument 2: list of guests
//	catalog.Set(language.English, "%[1]v invite(s) %[2]v to their party.",
//		plural.Selectf(1, "",
//			plural.One, gender.Select(1,
//				"female", "%[1]v invites %[2]v to her party."
//				"other", "%[1]v invites %[2]v to his party."),
//			plural.Other, "%[1]v invites %[2]v to their party."))
//
// Not necessarily shorter, but using variables there is less duplication and
// the messages are more maintenance friendly. Moreover, languages may have up
// to six plural forms. This makes the use of variables more welcome.
//
// Different messages using the same inflections can reuse variables by moving
// them to macros. Using macros we can rewrite the message as:
//
//	// argument 1: list of hosts, argument 2: list of guests
//	catalog.SetString(language.English, "%[1]v invite(s) %[2]v to their party.",
//		"%[1]v ${invites(1)} %[2]v to ${their(1)} party.")
//
// Where the following macros were defined separately.
//
//	catalog.SetMacro(language.English, "invites", plural.Selectf(1, "",
//		plural.One, "invite"))
//	catalog.SetMacro(language.English, "their", plural.Selectf(1, "",
//		plural.One, gender.Select(1, "female", "her", "other", "his"))),
//
// Placeholders use parentheses and the arguments to invoke a macro.
//
// # Looking up messages
//
// Message lookup using Catalogs is typically only done by specialized packages
// and is not something the user should be concerned with. For instance, to
// express the tardiness of a user using the related message we defined earlier,
// the user may use the package message like so:
//
//	p := message.NewPrinter(language.English)
//	p.Printf("You are %d minute(s) late.", 5)
//
// Which would print:
//
//	You are 5 minutes late.
//
// This package is UNDER CONSTRUCTION and its API may change.
package catalog // import "golang.org/x/text/message/catalog"

// TODO:
// Some way to freeze a catalog.
// - Locking on each lockup turns out to be about 50% of the total running time
//   for some of the benchmarks in the message package.
// Consider these:
// - Sequence type to support sequences in user-defined messages.
// - Garbage collection: Remove dictionaries that can no longer be reached
//   as other dictionaries have been added that cover all possible keys.

import (
	"errors"
	"fmt"

	"golang.org/x/text/internal"

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

// A Catalog allows lookup of translated messages.
type Catalog interface {
	// Languages returns all languages for which the Catalog contains variants.
	Languages() []language.Tag

	// Matcher returns a Matcher for languages from this Catalog.
	Matcher() language.Matcher

	// A Context is used for evaluating Messages.
	Context(tag language.Tag, r catmsg.Renderer) *Context

	// This method also makes Catalog a private interface.
	lookup(tag language.Tag, key string) (data string, ok bool)
}

// NewFromMap creates a Catalog from the given map. If a Dictionary is
// underspecified the entry is retrieved from a parent language.
func NewFromMap(dictionaries map[string]Dictionary, opts ...Option) (Catalog, error) {
	options := options{}
	for _, o := range opts {
		o(&options)
	}
	c := &catalog{
		dicts: map[language.Tag]Dictionary{},
	}
	_, hasFallback := dictionaries[options.fallback.String()]
	if hasFallback {
		// TODO: Should it be okay to not have a fallback language?
		// Catalog generators could enforce there is always a fallback.
		c.langs = append(c.langs, options.fallback)
	}
	for lang, dict := range dictionaries {
		tag, err := language.Parse(lang)
		if err != nil {
			return nil, fmt.Errorf("catalog: invalid language tag %q", lang)
		}
		if _, ok := c.dicts[tag]; ok {
			return nil, fmt.Errorf("catalog: duplicate entry for tag %q after normalization", tag)
		}
		c.dicts[tag] = dict
		if !hasFallback || tag != options.fallback {
			c.langs = append(c.langs, tag)
		}
	}
	if hasFallback {
		internal.SortTags(c.langs[1:])
	} else {
		internal.SortTags(c.langs)
	}
	c.matcher = language.NewMatcher(c.langs)
	return c, nil
}

// A Dictionary is a source of translations for a single language.
type Dictionary interface {
	// Lookup returns a message compiled with catmsg.Compile for the given key.
	// It returns false for ok if such a message could not be found.
	Lookup(key string) (data string, ok bool)
}

type catalog struct {
	langs   []language.Tag
	dicts   map[language.Tag]Dictionary
	macros  store
	matcher language.Matcher
}

func (c *catalog) Languages() []language.Tag { return c.langs }
func (c *catalog) Matcher() language.Matcher { return c.matcher }

func (c *catalog) lookup(tag language.Tag, key string) (data string, ok bool) {
	for ; ; tag = tag.Parent() {
		if dict, ok := c.dicts[tag]; ok {
			if data, ok := dict.Lookup(key); ok {
				return data, true
			}
		}
		if tag == language.Und {
			break
		}
	}
	return "", false
}

// Context returns a Context for formatting messages.
// Only one Message may be formatted per context at any given time.
func (c *catalog) Context(tag language.Tag, r catmsg.Renderer) *Context {
	return &Context{
		cat: c,
		tag: tag,
		dec: catmsg.NewDecoder(tag, r, &dict{&c.macros, tag}),
	}
}

// A Builder allows building a Catalog programmatically.
type Builder struct {
	options
	matcher language.Matcher

	index  store
	macros store
}

type options struct {
	fallback language.Tag
}

// An Option configures Catalog behavior.
type Option func(*options)

// Fallback specifies the default fallback language. The default is Und.
func Fallback(tag language.Tag) Option {
	return func(o *options) { o.fallback = tag }
}

// TODO:
// // Catalogs specifies one or more sources for a Catalog.
// // Lookups are in order.
// // This can be changed inserting a Catalog used for setting, which implements
// // Loader, used for setting in the chain.
// func Catalogs(d ...Loader) Option {
// 	return nil
// }
//
// func Delims(start, end string) Option {}
//
// func Dict(tag language.Tag, d ...Dictionary) Option

// NewBuilder returns an empty mutable Catalog.
func NewBuilder(opts ...Option) *Builder {
	c := &Builder{}
	for _, o := range opts {
		o(&c.options)
	}
	return c
}

// SetString is shorthand for Set(tag, key, String(msg)).
func (c *Builder) SetString(tag language.Tag, key string, msg string) error {
	return c.set(tag, key, &c.index, String(msg))
}

// Set sets the translation for the given language and key.
//
// When evaluation this message, the first Message in the sequence to msgs to
// evaluate to a string will be the message returned.
func (c *Builder) Set(tag language.Tag, key string, msg ...Message) error {
	return c.set(tag, key, &c.index, msg...)
}

// SetMacro defines a Message that may be substituted in another message.
// The arguments to a macro Message are passed as arguments in the
// placeholder the form "${foo(arg1, arg2)}".
func (c *Builder) SetMacro(tag language.Tag, name string, msg ...Message) error {
	return c.set(tag, name, &c.macros, msg...)
}

// ErrNotFound indicates there was no message for the given key.
var ErrNotFound = errors.New("catalog: message not found")

// String specifies a plain message string. It can be used as fallback if no
// other strings match or as a simple standalone message.
//
// It is an error to pass more than one String in a message sequence.
func String(name string) Message {
	return catmsg.String(name)
}

// Var sets a variable that may be substituted in formatting patterns using
// named substitution of the form "${name}". The name argument is used as a
// fallback if the statements do not produce a match. The statement sequence may
// not contain any Var calls.
//
// The name passed to a Var must be unique within message sequence.
func Var(name string, msg ...Message) Message {
	return &catmsg.Var{Name: name, Message: firstInSequence(msg)}
}

// Context returns a Context for formatting messages.
// Only one Message may be formatted per context at any given time.
func (b *Builder) Context(tag language.Tag, r catmsg.Renderer) *Context {
	return &Context{
		cat: b,
		tag: tag,
		dec: catmsg.NewDecoder(tag, r, &dict{&b.macros, tag}),
	}
}

// A Context is used for evaluating Messages.
// Only one Message may be formatted per context at any given time.
type Context struct {
	cat Catalog
	tag language.Tag // TODO: use compact index.
	dec *catmsg.Decoder
}

// Execute looks up and executes the message with the given key.
// It returns ErrNotFound if no message could be found in the index.
func (c *Context) Execute(key string) error {
	data, ok := c.cat.lookup(c.tag, key)
	if !ok {
		return ErrNotFound
	}
	return c.dec.Execute(data)
}
