// Copyright 2009 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 datafmt implements syntax-directed, type-driven formatting
	of arbitrary data structures. Formatting a data structure consists of
	two phases: first, a parser reads a format specification and builds a
	"compiled" format. Then, the format can be applied repeatedly to
	arbitrary values. Applying a format to a value evaluates to a []byte
	containing the formatted value bytes, or nil.

	A format specification is a set of package declarations and format rules:

		Format      = [ Entry { ";" Entry } [ ";" ] ] .
		Entry       = PackageDecl | FormatRule .

	(The syntax of a format specification is presented in the same EBNF
	notation as used in the Go language specification. The syntax of white
	space, comments, identifiers, and string literals is the same as in Go.)

	A package declaration binds a package name (such as 'ast') to a
	package import path (such as '"go/ast"'). Each package used (in
	a type name, see below) must be declared once before use.

		PackageDecl = PackageName ImportPath .
		PackageName = identifier .
		ImportPath  = string .

	A format rule binds a rule name to a format expression. A rule name
	may be a type name or one of the special names 'default' or '/'.
	A type name may be the name of a predeclared type (for example, 'int',
	'float32', etc.), the package-qualified name of a user-defined type
	(for example, 'ast.MapType'), or an identifier indicating the structure
	of unnamed composite types ('array', 'chan', 'func', 'interface', 'map',
	or 'ptr'). Each rule must have a unique name; rules can be declared in
	any order.

		FormatRule  = RuleName "=" Expression .
		RuleName    = TypeName | "default" | "/" .
		TypeName    = [ PackageName "." ] identifier .

	To format a value, the value's type name is used to select the format rule
	(there is an override mechanism, see below). The format expression of the
	selected rule specifies how the value is formatted. Each format expression,
	when applied to a value, evaluates to a byte sequence or nil.

	In its most general form, a format expression is a list of alternatives,
	each of which is a sequence of operands:

		Expression  = [ Sequence ] { "|" [ Sequence ] } .
		Sequence    = Operand { Operand } .

	The formatted result produced by an expression is the result of the first
	alternative sequence that evaluates to a non-nil result; if there is no
	such alternative, the expression evaluates to nil. The result produced by
	an operand sequence is the concatenation of the results of its operands.
	If any operand in the sequence evaluates to nil, the entire sequence
	evaluates to nil.

	There are five kinds of operands:

		Operand     = Literal | Field | Group | Option | Repetition .

	Literals evaluate to themselves, with two substitutions. First,
	%-formats expand in the manner of fmt.Printf, with the current value
	passed as the parameter. Second, the current indentation (see below)
	is inserted after every newline or form feed character.

		Literal     = string .

	This table shows string literals applied to the value 42 and the
	corresponding formatted result:

		"foo"       foo
		"%x"        2a
		"x = %d"    x = 42
		"%#x = %d"  0x2a = 42

	A field operand is a field name optionally followed by an alternate
	rule name. The field name may be an identifier or one of the special
	names @ or *.

		Field       = FieldName [ ":" RuleName ] .
		FieldName   = identifier | "@" | "*" .

	If the field name is an identifier, the current value must be a struct,
	and there must be a field with that name in the struct. The same lookup
	rules apply as in the Go language (for instance, the name of an anonymous
	field is the unqualified type name). The field name denotes the field
	value in the struct. If the field is not found, formatting is aborted
	and an error message is returned. (TODO consider changing the semantics
	such that if a field is not found, it evaluates to nil).

	The special name '@' denotes the current value.

	The meaning of the special name '*' depends on the type of the current
	value:

		array, slice types   array, slice element (inside {} only, see below)
		interfaces           value stored in interface
		pointers             value pointed to by pointer

	(Implementation restriction: channel, function and map types are not
	supported due to missing reflection support).

	Fields are evaluated as follows: If the field value is nil, or an array
	or slice element does not exist, the result is nil (see below for details
	on array/slice elements). If the value is not nil the field value is
	formatted (recursively) using the rule corresponding to its type name,
	or the alternate rule name, if given.

	The following example shows a complete format specification for a
	struct 'myPackage.Point'. Assume the package

		package myPackage  // in directory myDir/myPackage
		type Point struct {
			name string;
			x, y int;
		}

	Applying the format specification

		myPackage "myDir/myPackage";
		int = "%d";
		hexInt = "0x%x";
		string = "---%s---";
		myPackage.Point = name "{" x ", " y:hexInt "}";

	to the value myPackage.Point{"foo", 3, 15} results in

		---foo---{3, 0xf}

	Finally, an operand may be a grouped, optional, or repeated expression.
	A grouped expression ("group") groups a more complex expression (body)
	so that it can be used in place of a single operand:

		Group       = "(" [ Indentation ">>" ] Body ")" .
		Indentation = Expression .
		Body        = Expression .

	A group body may be prefixed by an indentation expression followed by '>>'.
	The indentation expression is applied to the current value like any other
	expression and the result, if not nil, is appended to the current indentation
	during the evaluation of the body (see also formatting state, below).

	An optional expression ("option") is enclosed in '[]' brackets.

		Option      = "[" Body "]" .

	An option evaluates to its body, except that if the body evaluates to nil,
	the option expression evaluates to an empty []byte. Thus an option's purpose
	is to protect the expression containing the option from a nil operand.

	A repeated expression ("repetition") is enclosed in '{}' braces.

		Repetition  = "{" Body [ "/" Separator ] "}" .
		Separator   = Expression .

	A repeated expression is evaluated as follows: The body is evaluated
	repeatedly and its results are concatenated until the body evaluates
	to nil. The result of the repetition is the (possibly empty) concatenation,
	but it is never nil. An implicit index is supplied for the evaluation of
	the body: that index is used to address elements of arrays or slices. If
	the corresponding elements do not exist, the field denoting the element
	evaluates to nil (which in turn may terminate the repetition).

	The body of a repetition may be followed by a '/' and a "separator"
	expression. If the separator is present, it is invoked between repetitions
	of the body.

	The following example shows a complete format specification for formatting
	a slice of unnamed type. Applying the specification

		int = "%b";
		array = { * / ", " };  // array is the type name for an unnamed slice

	to the value '[]int{2, 3, 5, 7}' results in

		10, 11, 101, 111

	Default rule: If a format rule named 'default' is present, it is used for
	formatting a value if no other rule was found. A common default rule is

		default = "%v"

	to provide default formatting for basic types without having to specify
	a specific rule for each basic type.

	Global separator rule: If a format rule named '/' is present, it is
	invoked with the current value between literals. If the separator
	expression evaluates to nil, it is ignored.

	For instance, a global separator rule may be used to punctuate a sequence
	of values with commas. The rules:

		default = "%v";
		/ = ", ";

	will format an argument list by printing each one in its default format,
	separated by a comma and a space.
*/
package datafmt

import (
	"bytes"
	"fmt"
	"go/token"
	"io"
	"os"
	"reflect"
	"runtime"
)

// ----------------------------------------------------------------------------
// Format representation

// Custom formatters implement the Formatter function type.
// A formatter is invoked with the current formatting state, the
// value to format, and the rule name under which the formatter
// was installed (the same formatter function may be installed
// under different names). The formatter may access the current state
// to guide formatting and use State.Write to append to the state's
// output.
//
// A formatter must return a boolean value indicating if it evaluated
// to a non-nil value (true), or a nil value (false).
//
type Formatter func(state *State, value interface{}, ruleName string) bool

// A FormatterMap is a set of custom formatters.
// It maps a rule name to a formatter function.
//
type FormatterMap map[string]Formatter

// A parsed format expression is built from the following nodes.
//
type (
	expr interface{}

	alternatives []expr // x | y | z

	sequence []expr // x y z

	literal [][]byte // a list of string segments, possibly starting with '%'

	field struct {
		fieldName string // including "@", "*"
		ruleName  string // "" if no rule name specified
	}

	group struct {
		indent, body expr // (indent >> body)
	}

	option struct {
		body expr // [body]
	}

	repetition struct {
		body, separator expr // {body / separator}
	}

	custom struct {
		ruleName string
		fun      Formatter
	}
)

// A Format is the result of parsing a format specification.
// The format may be applied repeatedly to format values.
//
type Format map[string]expr

// ----------------------------------------------------------------------------
// Formatting

// An application-specific environment may be provided to Format.Apply;
// the environment is available inside custom formatters via State.Env().
// Environments must implement copying; the Copy method must return an
// complete copy of the receiver. This is necessary so that the formatter
// can save and restore an environment (in case of an absent expression).
//
// If the Environment doesn't change during formatting (this is under
// control of the custom formatters), the Copy function can simply return
// the receiver, and thus can be very light-weight.
//
type Environment interface {
	Copy() Environment
}

// State represents the current formatting state.
// It is provided as argument to custom formatters.
//
type State struct {
	fmt       Format         // format in use
	env       Environment    // user-supplied environment
	errors    chan os.Error  // not chan *Error (errors <- nil would be wrong!)
	hasOutput bool           // true after the first literal has been written
	indent    bytes.Buffer   // current indentation
	output    bytes.Buffer   // format output
	linePos   token.Position // position of line beginning (Column == 0)
	default_  expr           // possibly nil
	separator expr           // possibly nil
}

func newState(fmt Format, env Environment, errors chan os.Error) *State {
	s := new(State)
	s.fmt = fmt
	s.env = env
	s.errors = errors
	s.linePos = token.Position{Line: 1}

	// if we have a default rule, cache its expression for fast access
	if x, found := fmt["default"]; found {
		s.default_ = x
	}

	// if we have a global separator rule, cache its expression for fast access
	if x, found := fmt["/"]; found {
		s.separator = x
	}

	return s
}

// Env returns the environment passed to Format.Apply.
func (s *State) Env() interface{} { return s.env }

// LinePos returns the position of the current line beginning
// in the state's output buffer. Line numbers start at 1.
//
func (s *State) LinePos() token.Position { return s.linePos }

// Pos returns the position of the next byte to be written to the
// output buffer. Line numbers start at 1.
//
func (s *State) Pos() token.Position {
	offs := s.output.Len()
	return token.Position{Line: s.linePos.Line, Column: offs - s.linePos.Offset, Offset: offs}
}

// Write writes data to the output buffer, inserting the indentation
// string after each newline or form feed character. It cannot return an error.
//
func (s *State) Write(data []byte) (int, os.Error) {
	n := 0
	i0 := 0
	for i, ch := range data {
		if ch == '\n' || ch == '\f' {
			// write text segment and indentation
			n1, _ := s.output.Write(data[i0 : i+1])
			n2, _ := s.output.Write(s.indent.Bytes())
			n += n1 + n2
			i0 = i + 1
			s.linePos.Offset = s.output.Len()
			s.linePos.Line++
		}
	}
	n3, _ := s.output.Write(data[i0:])
	return n + n3, nil
}

type checkpoint struct {
	env       Environment
	hasOutput bool
	outputLen int
	linePos   token.Position
}

func (s *State) save() checkpoint {
	saved := checkpoint{nil, s.hasOutput, s.output.Len(), s.linePos}
	if s.env != nil {
		saved.env = s.env.Copy()
	}
	return saved
}

func (s *State) restore(m checkpoint) {
	s.env = m.env
	s.output.Truncate(m.outputLen)
}

func (s *State) error(msg string) {
	s.errors <- os.NewError(msg)
	runtime.Goexit()
}

// TODO At the moment, unnamed types are simply mapped to the default
//      names below. For instance, all unnamed arrays are mapped to
//      'array' which is not really sufficient. Eventually one may want
//      to be able to specify rules for say an unnamed slice of T.
//

func typename(typ reflect.Type) string {
	switch typ.Kind() {
	case reflect.Array:
		return "array"
	case reflect.Slice:
		return "array"
	case reflect.Chan:
		return "chan"
	case reflect.Func:
		return "func"
	case reflect.Interface:
		return "interface"
	case reflect.Map:
		return "map"
	case reflect.Ptr:
		return "ptr"
	}
	return typ.String()
}

func (s *State) getFormat(name string) expr {
	if fexpr, found := s.fmt[name]; found {
		return fexpr
	}

	if s.default_ != nil {
		return s.default_
	}

	s.error(fmt.Sprintf("no format rule for type: '%s'", name))
	return nil
}

// eval applies a format expression fexpr to a value. If the expression
// evaluates internally to a non-nil []byte, that slice is appended to
// the state's output buffer and eval returns true. Otherwise, eval
// returns false and the state remains unchanged.
//
func (s *State) eval(fexpr expr, value reflect.Value, index int) bool {
	// an empty format expression always evaluates
	// to a non-nil (but empty) []byte
	if fexpr == nil {
		return true
	}

	switch t := fexpr.(type) {
	case alternatives:
		// append the result of the first alternative that evaluates to
		// a non-nil []byte to the state's output
		mark := s.save()
		for _, x := range t {
			if s.eval(x, value, index) {
				return true
			}
			s.restore(mark)
		}
		return false

	case sequence:
		// append the result of all operands to the state's output
		// unless a nil result is encountered
		mark := s.save()
		for _, x := range t {
			if !s.eval(x, value, index) {
				s.restore(mark)
				return false
			}
		}
		return true

	case literal:
		// write separator, if any
		if s.hasOutput {
			// not the first literal
			if s.separator != nil {
				sep := s.separator // save current separator
				s.separator = nil  // and disable it (avoid recursion)
				mark := s.save()
				if !s.eval(sep, value, index) {
					s.restore(mark)
				}
				s.separator = sep // enable it again
			}
		}
		s.hasOutput = true
		// write literal segments
		for _, lit := range t {
			if len(lit) > 1 && lit[0] == '%' {
				// segment contains a %-format at the beginning
				if lit[1] == '%' {
					// "%%" is printed as a single "%"
					s.Write(lit[1:])
				} else {
					// use s instead of s.output to get indentation right
					fmt.Fprintf(s, string(lit), value.Interface())
				}
			} else {
				// segment contains no %-formats
				s.Write(lit)
			}
		}
		return true // a literal never evaluates to nil

	case *field:
		// determine field value
		switch t.fieldName {
		case "@":
			// field value is current value

		case "*":
			// indirection: operation is type-specific
			switch v := value; v.Kind() {
			case reflect.Array:
				if v.Len() <= index {
					return false
				}
				value = v.Index(index)

			case reflect.Slice:
				if v.IsNil() || v.Len() <= index {
					return false
				}
				value = v.Index(index)

			case reflect.Map:
				s.error("reflection support for maps incomplete")

			case reflect.Ptr:
				if v.IsNil() {
					return false
				}
				value = v.Elem()

			case reflect.Interface:
				if v.IsNil() {
					return false
				}
				value = v.Elem()

			case reflect.Chan:
				s.error("reflection support for chans incomplete")

			case reflect.Func:
				s.error("reflection support for funcs incomplete")

			default:
				s.error(fmt.Sprintf("error: * does not apply to `%s`", value.Type()))
			}

		default:
			// value is value of named field
			var field reflect.Value
			if sval := value; sval.Kind() == reflect.Struct {
				field = sval.FieldByName(t.fieldName)
				if !field.IsValid() {
					// TODO consider just returning false in this case
					s.error(fmt.Sprintf("error: no field `%s` in `%s`", t.fieldName, value.Type()))
				}
			}
			value = field
		}

		// determine rule
		ruleName := t.ruleName
		if ruleName == "" {
			// no alternate rule name, value type determines rule
			ruleName = typename(value.Type())
		}
		fexpr = s.getFormat(ruleName)

		mark := s.save()
		if !s.eval(fexpr, value, index) {
			s.restore(mark)
			return false
		}
		return true

	case *group:
		// remember current indentation
		indentLen := s.indent.Len()

		// update current indentation
		mark := s.save()
		s.eval(t.indent, value, index)
		// if the indentation evaluates to nil, the state's output buffer
		// didn't change - either way it's ok to append the difference to
		// the current indentation
		s.indent.Write(s.output.Bytes()[mark.outputLen:s.output.Len()])
		s.restore(mark)

		// format group body
		mark = s.save()
		b := true
		if !s.eval(t.body, value, index) {
			s.restore(mark)
			b = false
		}

		// reset indentation
		s.indent.Truncate(indentLen)
		return b

	case *option:
		// evaluate the body and append the result to the state's output
		// buffer unless the result is nil
		mark := s.save()
		if !s.eval(t.body, value, 0) { // TODO is 0 index correct?
			s.restore(mark)
		}
		return true // an option never evaluates to nil

	case *repetition:
		// evaluate the body and append the result to the state's output
		// buffer until a result is nil
		for i := 0; ; i++ {
			mark := s.save()
			// write separator, if any
			if i > 0 && t.separator != nil {
				// nil result from separator is ignored
				mark := s.save()
				if !s.eval(t.separator, value, i) {
					s.restore(mark)
				}
			}
			if !s.eval(t.body, value, i) {
				s.restore(mark)
				break
			}
		}
		return true // a repetition never evaluates to nil

	case *custom:
		// invoke the custom formatter to obtain the result
		mark := s.save()
		if !t.fun(s, value.Interface(), t.ruleName) {
			s.restore(mark)
			return false
		}
		return true
	}

	panic("unreachable")
	return false
}

// Eval formats each argument according to the format
// f and returns the resulting []byte and os.Error. If
// an error occurred, the []byte contains the partially
// formatted result. An environment env may be passed
// in which is available in custom formatters through
// the state parameter.
//
func (f Format) Eval(env Environment, args ...interface{}) ([]byte, os.Error) {
	if f == nil {
		return nil, os.NewError("format is nil")
	}

	errors := make(chan os.Error)
	s := newState(f, env, errors)

	go func() {
		for _, v := range args {
			fld := reflect.ValueOf(v)
			if !fld.IsValid() {
				errors <- os.NewError("nil argument")
				return
			}
			mark := s.save()
			if !s.eval(s.getFormat(typename(fld.Type())), fld, 0) { // TODO is 0 index correct?
				s.restore(mark)
			}
		}
		errors <- nil // no errors
	}()

	err := <-errors
	return s.output.Bytes(), err
}

// ----------------------------------------------------------------------------
// Convenience functions

// Fprint formats each argument according to the format f
// and writes to w. The result is the total number of bytes
// written and an os.Error, if any.
//
func (f Format) Fprint(w io.Writer, env Environment, args ...interface{}) (int, os.Error) {
	data, err := f.Eval(env, args...)
	if err != nil {
		// TODO should we print partial result in case of error?
		return 0, err
	}
	return w.Write(data)
}

// Print formats each argument according to the format f
// and writes to standard output. The result is the total
// number of bytes written and an os.Error, if any.
//
func (f Format) Print(args ...interface{}) (int, os.Error) {
	return f.Fprint(os.Stdout, nil, args...)
}

// Sprint formats each argument according to the format f
// and returns the resulting string. If an error occurs
// during formatting, the result string contains the
// partially formatted result followed by an error message.
//
func (f Format) Sprint(args ...interface{}) string {
	var buf bytes.Buffer
	_, err := f.Fprint(&buf, nil, args...)
	if err != nil {
		var i interface{} = args
		fmt.Fprintf(&buf, "--- Sprint(%s) failed: %v", fmt.Sprint(i), err)
	}
	return buf.String()
}
