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

/*	The datafmt package 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 : len(data)]);
	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.(type) {
	case *reflect.ArrayType:
		return "array";
	case *reflect.SliceType:
		return "array";
	case *reflect.ChanType:
		return "chan";
	case *reflect.DotDotDotType:
		return "ellipsis";
	case *reflect.FuncType:
		return "func";
	case *reflect.InterfaceType:
		return "interface";
	case *reflect.MapType:
		return "map";
	case *reflect.PtrType:
		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 : len(lit)]);
				} 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.(type) {
			case *reflect.ArrayValue:
				if v.Len() <= index {
					return false;
				}
				value = v.Elem(index);

			case *reflect.SliceValue:
				if v.IsNil() || v.Len() <= index {
					return false;
				}
				value = v.Elem(index);

			case *reflect.MapValue:
				s.error("reflection support for maps incomplete");

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

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

			case *reflect.ChanValue:
				s.error("reflection support for chans incomplete");

			case *reflect.FuncValue:
				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, ok := value.(*reflect.StructValue); ok {
				field = sval.FieldByName(t.fieldName);
				if field == nil {
					// 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 identation
		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 occured, 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 ...) ([]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() {
		value := reflect.NewValue(args).(*reflect.StructValue);
		for i := 0; i < value.NumField(); i++ {
			fld := value.Field(i);
			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 ...) (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 ...) (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 ...) string {
	var buf bytes.Buffer;
	_, err := f.Fprint(&buf, nil, args);
	if err != nil {
		fmt.Fprintf(&buf, "--- Sprint(%s) failed: %v", fmt.Sprint(args), err);
	}
	return buf.String();
}
