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

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

// FirstOf is a message type that prints the first message in the sequence that
// resolves to a match for the given substitution arguments.
type FirstOf []Message

// Compile implements Message.
func (s FirstOf) Compile(e *Encoder) error {
	e.EncodeMessageType(msgFirst)
	err := ErrIncomplete
	for i, m := range s {
		if err == nil {
			return fmt.Errorf("catalog: message argument %d is complete and blocks subsequent messages", i-1)
		}
		err = e.EncodeMessage(m)
	}
	return 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
}
