// 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(1)
//   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
}
