// 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 it's expression for fast access
	if x, found := fmt["default"]; found {
		s.default_ = x
	}

	// if we have a global separator rule, cache it's 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()
}
