// 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 catmsg contains support types for package x/text/message/catalog.
//
// This package contains the low-level implementations of Message used by the
// catalog package and provides primitives for other packages to implement their
// own. For instance, the plural package provides functionality for selecting
// translation strings based on the plural category of substitution arguments.
//
//
// Encoding and Decoding
//
// Catalogs store Messages encoded as a single string. Compiling a message into
// a string both results in compacter representation and speeds up evaluation.
//
// A Message must implement a Compile method to convert its arbitrary
// representation to a string. The Compile method takes an Encoder which
// facilitates serializing the message. Encoders also provide more context of
// the messages's creation (such as for which language the message is intended),
// which may not be known at the time of the creation of the message.
//
// Each message type must also have an accompanying decoder registered to decode
// the message. This decoder takes a Decoder argument which provides the
// counterparts for the decoding.
//
//
// Renderers
//
// A Decoder must be initialized with a Renderer implementation. These
// implementations must be provided by packages that use Catalogs, typically
// formatting packages such as x/text/message. A typical user will not need to
// worry about this type; it is only relevant to packages that do string
// formatting and want to use the catalog package to handle localized strings.
//
// A package that uses catalogs for selecting strings receives selection results
// as sequence of substrings passed to the Renderer. The following snippet shows
// how to express the above example using the message package.
//
//   message.Set(language.English, "You are %d minute(s) late.",
//       catalog.Var("minutes", plural.Select(1, "one", "minute")),
//       catalog.String("You are %[1]d ${minutes} late."))
//
//   p := message.NewPrinter(language.English)
//   p.Printf("You are %d minute(s) late.", 5) // always 5 minutes late.
//
// To evaluate the Printf, package message wraps the arguments in a Renderer
// that is passed to the catalog for message decoding. The call sequence that
// results from evaluating the above message, assuming the person is rather
// tardy, is:
//
//   Render("You are %[1]d ")
//   Arg(1)
//   Render("minutes")
//   Render(" late.")
//
// The calls to Arg is caused by the plural.Select execution, which evaluates
// the argument to determine whether the singular or plural message form should
// be selected. The calls to Render reports the partial results to the message
// package for further evaluation.
package catmsg

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
	"sync"

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

// A Handle refers to a registered message type.
type Handle int

// First is used as a Handle to EncodeMessageType, followed by a series of calls
// to EncodeMessage, to implement selecting the first matching Message.
//
// TODO: this can be removed once we either can use type aliases or if the
// internals of this package are merged with the catalog package.
var First Handle = msgFirst

// A Handler decodes and evaluates data compiled by a Message and sends the
// result to the Decoder. The output may depend on the value of the substitution
// arguments, accessible by the Decoder's Arg method. The Handler returns false
// if there is no translation for the given substitution arguments.
type Handler func(d *Decoder) bool

// Register records the existence of a message type and returns a Handle that
// can be used in the Encoder's EncodeMessageType method to create such
// messages. The prefix of the name should be the package path followed by
// an optional disambiguating string.
// Register will panic if a handle for the same name was already registered.
func Register(name string, handler Handler) Handle {
	mutex.Lock()
	defer mutex.Unlock()

	if _, ok := names[name]; ok {
		panic(fmt.Errorf("catmsg: handler for %q already exists", name))
	}
	h := Handle(len(handlers))
	names[name] = h
	handlers = append(handlers, handler)
	return h
}

// These handlers require fixed positions in the handlers slice.
const (
	msgVars Handle = iota
	msgFirst
	msgRaw
	msgString
	numFixed
)

const prefix = "golang.org/x/text/internal/catmsg."

var (
	mutex sync.Mutex
	names = map[string]Handle{
		prefix + "Vars":   msgVars,
		prefix + "First":  msgFirst,
		prefix + "Raw":    msgRaw,
		prefix + "String": msgString,
	}
	handlers = make([]Handler, numFixed)
)

func init() {
	// This handler is a message type wrapper that initializes a decoder
	// with a variable block. This message type, if present, is always at the
	// start of an encoded message.
	handlers[msgVars] = func(d *Decoder) bool {
		blockSize := int(d.DecodeUint())
		d.vars = d.data[:blockSize]
		d.data = d.data[blockSize:]
		return d.executeMessage()
	}

	// First takes the first message in a sequence that results in a match for
	// the given substitution arguments.
	handlers[msgFirst] = func(d *Decoder) bool {
		for !d.Done() {
			if d.ExecuteMessage() {
				return true
			}
		}
		return false
	}

	handlers[msgRaw] = func(d *Decoder) bool {
		d.Render(d.data)
		return true
	}

	// A String message alternates between a string constant and a variable
	// substitution.
	handlers[msgString] = func(d *Decoder) bool {
		for !d.Done() {
			if str := d.DecodeString(); str != "" {
				d.Render(str)
			}
			if d.Done() {
				break
			}
			d.ExecuteSubstitution()
		}
		return true
	}
}

var (
	// ErrIncomplete indicates a compiled message does not define translations
	// for all possible argument values. If this message is returned, evaluating
	// a message may result in the ErrNoMatch error.
	ErrIncomplete = errors.New("catmsg: incomplete message; may not give result for all inputs")

	// ErrNoMatch indicates no translation message matched the given input
	// parameters when evaluating a message.
	ErrNoMatch = errors.New("catmsg: no translation for inputs")
)

// A Message holds a collection of translations for the same phrase that may
// vary based on the values of substitution arguments.
type Message interface {
	// Compile encodes the format string(s) of the message as a string for later
	// evaluation.
	//
	// The first call Compile makes on the encoder must be EncodeMessageType.
	// The handle passed to this call may either be a handle returned by
	// Register to encode a single custom message, or HandleFirst followed by
	// a sequence of calls to EncodeMessage.
	//
	// Compile must return ErrIncomplete if it is possible for evaluation to
	// not match any translation for a given set of formatting parameters.
	// For example, selecting a translation based on plural form may not yield
	// a match if the form "Other" is not one of the selectors.
	//
	// Compile may return any other application-specific error. For backwards
	// compatibility with package like fmt, which often do not do sanity
	// checking of format strings ahead of time, Compile should still make an
	// effort to have some sensible fallback in case of an error.
	Compile(e *Encoder) error
}

// Compile converts a Message to a data string that can be stored in a Catalog.
// The resulting string can subsequently be decoded by passing to the Execute
// method of a Decoder.
func Compile(tag language.Tag, macros Dictionary, m Message) (data string, err error) {
	// TODO: pass macros so they can be used for validation.
	v := &Encoder{inBody: true} // encoder for variables
	v.root = v
	e := &Encoder{root: v, parent: v, tag: tag} // encoder for messages
	err = m.Compile(e)
	// This package serves te message package, which in turn is meant to be a
	// drop-in replacement for fmt.  With the fmt package, format strings are
	// evaluated lazily and errors are handled by substituting strings in the
	// result, rather then returning an error. Dealing with multiple languages
	// makes it more important to check errors ahead of time. We chose to be
	// consistent and compatible and allow graceful degradation in case of
	// errors.
	buf := e.buf[stripPrefix(e.buf):]
	if len(v.buf) > 0 {
		// Prepend variable block.
		b := make([]byte, 1+maxVarintBytes+len(v.buf)+len(buf))
		b[0] = byte(msgVars)
		b = b[:1+encodeUint(b[1:], uint64(len(v.buf)))]
		b = append(b, v.buf...)
		b = append(b, buf...)
		buf = b
	}
	if err == nil {
		err = v.err
	}
	return string(buf), err
}

// Var defines a message that can be substituted for a placeholder of the same
// name. If an expression does not result in a string after evaluation, Name is
// used as the substitution. For example:
//    Var{
//      Name:    "minutes",
//      Message: plural.Select(1, "one", "minute"),
//    }
// will resolve to minute for singular and minutes for plural forms.
type Var struct {
	Name    string
	Message Message
}

var errIsVar = errors.New("catmsg: variable used as message")

// Compile implements Message.
//
// Note that this method merely registers a variable; it does not create an
// encoded message.
func (v *Var) Compile(e *Encoder) error {
	if err := e.addVar(v.Name, v.Message); err != nil {
		return err
	}
	// Using a Var by itself is an error. If it is in a sequence followed by
	// other messages referring to it, this error will be ignored.
	return errIsVar
}

// Raw is a message consisting of a single format string that is passed as is
// to the Renderer.
//
// Note that a Renderer may still do its own variable substitution.
type Raw string

// Compile implements Message.
func (r Raw) Compile(e *Encoder) (err error) {
	e.EncodeMessageType(msgRaw)
	// Special case: raw strings don't have a size encoding and so don't use
	// EncodeString.
	e.buf = append(e.buf, r...)
	return nil
}

// String is a message consisting of a single format string which contains
// placeholders that may be substituted with variables.
//
// Variable substitutions are marked with placeholders and a variable name of
// the form ${name}. Any other substitutions such as Go templates or
// printf-style substitutions are left to be done by the Renderer.
//
// When evaluation a string interpolation, a Renderer will receive separate
// calls for each placeholder and interstitial string. For example, for the
// message: "%[1]v ${invites} %[2]v to ${their} party." The sequence of calls
// is:
//   d.Render("%[1]v ")
//   d.Arg(1)
//   d.Render(resultOfInvites)
//   d.Render(" %[2]v to ")
//   d.Arg(2)
//   d.Render(resultOfTheir)
//   d.Render(" party.")
// where the messages for "invites" and "their" both use a plural.Select
// referring to the first argument.
//
// Strings may also invoke macros. Macros are essentially variables that can be
// reused. Macros may, for instance, be used to make selections between
// different conjugations of a verb. See the catalog package description for an
// overview of macros.
type String string

// Compile implements Message. It parses the placeholder formats and returns
// any error.
func (s String) Compile(e *Encoder) (err error) {
	msg := string(s)
	const subStart = "${"
	hasHeader := false
	p := 0
	b := []byte{}
	for {
		i := strings.Index(msg[p:], subStart)
		if i == -1 {
			break
		}
		b = append(b, msg[p:p+i]...)
		p += i + len(subStart)
		if i = strings.IndexByte(msg[p:], '}'); i == -1 {
			b = append(b, "$!(MISSINGBRACE)"...)
			err = fmt.Errorf("catmsg: missing '}'")
			p = len(msg)
			break
		}
		name := strings.TrimSpace(msg[p : p+i])
		if q := strings.IndexByte(name, '('); q == -1 {
			if !hasHeader {
				hasHeader = true
				e.EncodeMessageType(msgString)
			}
			e.EncodeString(string(b))
			e.EncodeSubstitution(name)
			b = b[:0]
		} else if j := strings.IndexByte(name[q:], ')'); j == -1 {
			// TODO: what should the error be?
			b = append(b, "$!(MISSINGPAREN)"...)
			err = fmt.Errorf("catmsg: missing ')'")
		} else if x, sErr := strconv.ParseUint(strings.TrimSpace(name[q+1:q+j]), 10, 32); sErr != nil {
			// TODO: handle more than one argument
			b = append(b, "$!(BADNUM)"...)
			err = fmt.Errorf("catmsg: invalid number %q", strings.TrimSpace(name[q+1:q+j]))
		} else {
			if !hasHeader {
				hasHeader = true
				e.EncodeMessageType(msgString)
			}
			e.EncodeString(string(b))
			e.EncodeSubstitution(name[:q], int(x))
			b = b[:0]
		}
		p += i + 1
	}
	b = append(b, msg[p:]...)
	if !hasHeader {
		// Simplify string to a raw string.
		Raw(string(b)).Compile(e)
	} else if len(b) > 0 {
		e.EncodeString(string(b))
	}
	return err
}
