// 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.Select:
//
//   catalog.Set(language.English, "You are %d minute(s) late.",
//       plural.Select(1,
//           "one", "You are 1 minute late.",
//           "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.Select(1, "one", "minute", "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.Select(1, "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.Select(1,
//             "one", gender.Select(1, "female", "her", "other", "his"))),
//     catalog.Var("invites", plural.Select(1, "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.Select(1,
//         "one", gender.Select(1,
//             "female", "%[1]v invites %[2]v to her party."
//             "other", "%[1]v invites %[2]v to his party."),
//         "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.Select(1, "one", "invite"))
//   catalog.SetMacro(language.English, "their", plural.Select(1,
//      "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)
}
