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

/*
	Data-driven templates for generating textual output such as
	HTML. See
		http://code.google.com/p/json-template/wiki/Reference
	for full documentation of the template language. A summary:

	Templates are executed by applying them to a data structure.
	Annotations in the template refer to elements of the data
	structure (typically a field of a struct) to control execution
	and derive values to be displayed.  The template walks the
	structure as it executes and the "cursor" @ represents the
	value at the current location in the structure.

	Data items may be values or pointers; the interface hides the
	indirection.

	Major constructs ({} are metacharacters; [] marks optional elements):

		{# comment }

	A one-line comment.

		{.section field} XXX [ {.or} YYY ] {.end}

	Set @ to the value of the field.  It may be an explicit @
	to stay at the same point in the data. If the field is nil
	or empty, execute YYY; otherwise execute XXX.

		{.repeated section field} XXX [ {.alternates with} ZZZ ] [ {.or} YYY ] {.end}

	Like .section, but field must be an array or slice.  XXX
	is executed for each element.  If the array is nil or empty,
	YYY is executed instead.  If the {.alternates with} marker
	is present, ZZZ is executed between iterations of XXX.

		{field}
		{field|formatter}

	Insert the value of the field into the output. Field is
	first looked for in the cursor, as in .section and .repeated.
	If it is not found, the search continues in outer sections
	until the top level is reached.

	If a formatter is specified, it must be named in the formatter
	map passed to the template set up routines or in the default
	set ("html","str","") and is used to process the data for
	output.  The formatter function has signature
		func(wr io.Write, data interface{}, formatter string)
	where wr is the destination for output, data is the field
	value, and formatter is its name at the invocation site.
*/
package template

import (
	"container/vector";
	"fmt";
	"io";
	"os";
	"reflect";
	"runtime";
	"strings";
)

// Errors returned during parsing and execution.  Users may extract the information and reformat
// if they desire.
type Error struct {
	Line	int;
	Msg	string;
}

func (e *Error) String() string	{ return fmt.Sprintf("line %d: %s", e.Line, e.Msg) }

// Most of the literals are aces.
var lbrace = []byte{'{'}
var rbrace = []byte{'}'}
var space = []byte{' '}
var tab = []byte{'\t'}

// The various types of "tokens", which are plain text or (usually) brace-delimited descriptors
const (
	tokAlternates	= iota;
	tokComment;
	tokEnd;
	tokLiteral;
	tokOr;
	tokRepeated;
	tokSection;
	tokText;
	tokVariable;
)

// FormatterMap is the type describing the mapping from formatter
// names to the functions that implement them.
type FormatterMap map[string]func(io.Writer, interface{}, string)

// Built-in formatters.
var builtins = FormatterMap{
	"html": HTMLFormatter,
	"str": StringFormatter,
	"": StringFormatter,
}

// The parsed state of a template is a vector of xxxElement structs.
// Sections have line numbers so errors can be reported better during execution.

// Plain text.
type textElement struct {
	text []byte;
}

// A literal such as .meta-left or .meta-right
type literalElement struct {
	text []byte;
}

// A variable to be evaluated
type variableElement struct {
	linenum		int;
	name		string;
	formatter	string;	// TODO(r): implement pipelines
}

// A .section block, possibly with a .or
type sectionElement struct {
	linenum	int;	// of .section itself
	field	string;	// cursor field for this block
	start	int;	// first element
	or	int;	// first element of .or block
	end	int;	// one beyond last element
}

// A .repeated block, possibly with a .or and a .alternates
type repeatedElement struct {
	sectionElement;		// It has the same structure...
	altstart	int;	// ... except for alternates
	altend		int;
}

// Template is the type that represents a template definition.
// It is unchanged after parsing.
type Template struct {
	fmap	FormatterMap;	// formatters for variables
	// Used during parsing:
	ldelim, rdelim	[]byte;		// delimiters; default {}
	buf		[]byte;		// input text to process
	p		int;		// position in buf
	linenum		int;		// position in input
	error		os.Error;	// error during parsing (only)
	// Parsed results:
	elems	*vector.Vector;
}

// Internal state for executing a Template.  As we evaluate the struct,
// the data item descends into the fields associated with sections, etc.
// Parent is used to walk upwards to find variables higher in the tree.
type state struct {
	parent	*state;		// parent in hierarchy
	data	reflect.Value;	// the driver data for this section etc.
	wr	io.Writer;	// where to send output
	errors	chan os.Error;	// for reporting errors during execute
}

func (parent *state) clone(data reflect.Value) *state {
	return &state{parent, data, parent.wr, parent.errors}
}

// New creates a new template with the specified formatter map (which
// may be nil) to define auxiliary functions for formatting variables.
func New(fmap FormatterMap) *Template {
	t := new(Template);
	t.fmap = fmap;
	t.ldelim = lbrace;
	t.rdelim = rbrace;
	t.elems = vector.New(0);
	return t;
}

// Report error and stop executing.  The line number must be provided explicitly.
func (t *Template) execError(st *state, line int, err string, args ...) {
	st.errors <- &Error{line, fmt.Sprintf(err, args)};
	runtime.Goexit();
}

// Report error, save in Template to terminate parsing.
// The line number comes from the template state.
func (t *Template) parseError(err string, args ...) {
	t.error = &Error{t.linenum, fmt.Sprintf(err, args)}
}

// -- Lexical analysis

// Is c a white space character?
func white(c uint8) bool	{ return c == ' ' || c == '\t' || c == '\r' || c == '\n' }

// Safely, does s[n:n+len(t)] == t?
func equal(s []byte, n int, t []byte) bool {
	b := s[n:len(s)];
	if len(t) > len(b) {	// not enough space left for a match.
		return false
	}
	for i, c := range t {
		if c != b[i] {
			return false
		}
	}
	return true;
}

// nextItem returns the next item from the input buffer.  If the returned
// item is empty, we are at EOF.  The item will be either a
// delimited string or a non-empty string between delimited
// strings. Tokens stop at (but include, if plain text) a newline.
// Action tokens on a line by themselves drop the white space on
// either side, up to and including the newline.
func (t *Template) nextItem() []byte {
	sawLeft := false;	// are we waiting for an opening delimiter?
	special := false;	// is this a {.foo} directive, which means trim white space?
	// Delete surrounding white space if this {.foo} is the only thing on the line.
	trim_white := t.p == 0 || t.buf[t.p-1] == '\n';
	only_white := true;	// we have seen only white space so far
	var i int;
	start := t.p;
Loop:
	for i = t.p; i < len(t.buf); i++ {
		switch {
		case t.buf[i] == '\n':
			t.linenum++;
			i++;
			break Loop;
		case white(t.buf[i]):
			// white space, do nothing
		case !sawLeft && equal(t.buf, i, t.ldelim):	// sawLeft checked because delims may be equal
			// anything interesting already on the line?
			if !only_white {
				break Loop
			}
			// is it a directive or comment?
			j := i + len(t.ldelim);	// position after delimiter
			if j+1 < len(t.buf) && (t.buf[j] == '.' || t.buf[j] == '#') {
				special = true;
				if trim_white && only_white {
					start = i
				}
			} else if i > t.p {	// have some text accumulated so stop before delimiter
				break Loop
			}
			sawLeft = true;
			i = j - 1;
		case equal(t.buf, i, t.rdelim):
			if !sawLeft {
				t.parseError("unmatched closing delimiter");
				return nil;
			}
			sawLeft = false;
			i += len(t.rdelim);
			break Loop;
		default:
			only_white = false
		}
	}
	if sawLeft {
		t.parseError("unmatched opening delimiter");
		return nil;
	}
	item := t.buf[start:i];
	if special && trim_white {
		// consume trailing white space
		for ; i < len(t.buf) && white(t.buf[i]); i++ {
			if t.buf[i] == '\n' {
				t.linenum++;
				i++;
				break;	// stop after newline
			}
		}
	}
	t.p = i;
	return item;
}

// Turn a byte array into a white-space-split array of strings.
func words(buf []byte) []string {
	s := make([]string, 0, 5);
	p := 0;	// position in buf
	// one word per loop
	for i := 0; ; i++ {
		// skip white space
		for ; p < len(buf) && white(buf[p]); p++ {
		}
		// grab word
		start := p;
		for ; p < len(buf) && !white(buf[p]); p++ {
		}
		if start == p {	// no text left
			break
		}
		if i == cap(s) {
			ns := make([]string, 2*cap(s));
			for j := range s {
				ns[j] = s[j]
			}
			s = ns;
		}
		s = s[0 : i+1];
		s[i] = string(buf[start:p]);
	}
	return s;
}

// Analyze an item and return its token type and, if it's an action item, an array of
// its constituent words.
func (t *Template) analyze(item []byte) (tok int, w []string) {
	// item is known to be non-empty
	if !equal(item, 0, t.ldelim) {	// doesn't start with left delimiter
		tok = tokText;
		return;
	}
	if !equal(item, len(item)-len(t.rdelim), t.rdelim) {	// doesn't end with right delimiter
		t.parseError("internal error: unmatched opening delimiter");	// lexing should prevent this
		return;
	}
	if len(item) <= len(t.ldelim)+len(t.rdelim) {	// no contents
		t.parseError("empty directive");
		return;
	}
	// Comment
	if item[len(t.ldelim)] == '#' {
		tok = tokComment;
		return;
	}
	// Split into words
	w = words(item[len(t.ldelim) : len(item)-len(t.rdelim)]);	// drop final delimiter
	if len(w) == 0 {
		t.parseError("empty directive");
		return;
	}
	if len(w) == 1 && w[0][0] != '.' {
		tok = tokVariable;
		return;
	}
	switch w[0] {
	case ".meta-left", ".meta-right", ".space", ".tab":
		tok = tokLiteral;
		return;
	case ".or":
		tok = tokOr;
		return;
	case ".end":
		tok = tokEnd;
		return;
	case ".section":
		if len(w) != 2 {
			t.parseError("incorrect fields for .section: %s", item);
			return;
		}
		tok = tokSection;
		return;
	case ".repeated":
		if len(w) != 3 || w[1] != "section" {
			t.parseError("incorrect fields for .repeated: %s", item);
			return;
		}
		tok = tokRepeated;
		return;
	case ".alternates":
		if len(w) != 2 || w[1] != "with" {
			t.parseError("incorrect fields for .alternates: %s", item);
			return;
		}
		tok = tokAlternates;
		return;
	}
	t.parseError("bad directive: %s", item);
	return;
}

// -- Parsing

// Allocate a new variable-evaluation element.
func (t *Template) newVariable(name_formatter string) (v *variableElement) {
	name := name_formatter;
	formatter := "";
	bar := strings.Index(name_formatter, "|");
	if bar >= 0 {
		name = name_formatter[0:bar];
		formatter = name_formatter[bar+1 : len(name_formatter)];
	}
	// Probably ok, so let's build it.
	v = &variableElement{t.linenum, name, formatter};

	// We could remember the function address here and avoid the lookup later,
	// but it's more dynamic to let the user change the map contents underfoot.
	// We do require the name to be present, though.

	// Is it in user-supplied map?
	if t.fmap != nil {
		if _, ok := t.fmap[formatter]; ok {
			return
		}
	}
	// Is it in builtin map?
	if _, ok := builtins[formatter]; ok {
		return
	}
	t.parseError("unknown formatter: %s", formatter);
	return;
}

// Grab the next item.  If it's simple, just append it to the template.
// Otherwise return its details.
func (t *Template) parseSimple(item []byte) (done bool, tok int, w []string) {
	tok, w = t.analyze(item);
	if t.error != nil {
		return
	}
	done = true;	// assume for simplicity
	switch tok {
	case tokComment:
		return
	case tokText:
		t.elems.Push(&textElement{item});
		return;
	case tokLiteral:
		switch w[0] {
		case ".meta-left":
			t.elems.Push(&literalElement{t.ldelim})
		case ".meta-right":
			t.elems.Push(&literalElement{t.rdelim})
		case ".space":
			t.elems.Push(&literalElement{space})
		case ".tab":
			t.elems.Push(&literalElement{tab})
		default:
			t.parseError("internal error: unknown literal: %s", w[0]);
			return;
		}
		return;
	case tokVariable:
		t.elems.Push(t.newVariable(w[0]));
		return;
	}
	return false, tok, w;
}

// parseRepeated and parseSection are mutually recursive

func (t *Template) parseRepeated(words []string) *repeatedElement {
	r := new(repeatedElement);
	t.elems.Push(r);
	r.linenum = t.linenum;
	r.field = words[2];
	// Scan section, collecting true and false (.or) blocks.
	r.start = t.elems.Len();
	r.or = -1;
	r.altstart = -1;
	r.altend = -1;
Loop:
	for t.error == nil {
		item := t.nextItem();
		if t.error != nil {
			break
		}
		if len(item) == 0 {
			t.parseError("missing .end for .repeated section");
			break;
		}
		done, tok, w := t.parseSimple(item);
		if t.error != nil {
			break
		}
		if done {
			continue
		}
		switch tok {
		case tokEnd:
			break Loop
		case tokOr:
			if r.or >= 0 {
				t.parseError("extra .or in .repeated section");
				break Loop;
			}
			r.altend = t.elems.Len();
			r.or = t.elems.Len();
		case tokSection:
			t.parseSection(w)
		case tokRepeated:
			t.parseRepeated(w)
		case tokAlternates:
			if r.altstart >= 0 {
				t.parseError("extra .alternates in .repeated section");
				break Loop;
			}
			if r.or >= 0 {
				t.parseError(".alternates inside .or block in .repeated section");
				break Loop;
			}
			r.altstart = t.elems.Len();
		default:
			t.parseError("internal error: unknown repeated section item: %s", item);
			break Loop;
		}
	}
	if t.error != nil {
		return nil
	}
	if r.altend < 0 {
		r.altend = t.elems.Len()
	}
	r.end = t.elems.Len();
	return r;
}

func (t *Template) parseSection(words []string) *sectionElement {
	s := new(sectionElement);
	t.elems.Push(s);
	s.linenum = t.linenum;
	s.field = words[1];
	// Scan section, collecting true and false (.or) blocks.
	s.start = t.elems.Len();
	s.or = -1;
Loop:
	for t.error == nil {
		item := t.nextItem();
		if t.error != nil {
			break
		}
		if len(item) == 0 {
			t.parseError("missing .end for .section");
			break;
		}
		done, tok, w := t.parseSimple(item);
		if t.error != nil {
			break
		}
		if done {
			continue
		}
		switch tok {
		case tokEnd:
			break Loop
		case tokOr:
			if s.or >= 0 {
				t.parseError("extra .or in .section");
				break Loop;
			}
			s.or = t.elems.Len();
		case tokSection:
			t.parseSection(w)
		case tokRepeated:
			t.parseRepeated(w)
		case tokAlternates:
			t.parseError(".alternates not in .repeated")
		default:
			t.parseError("internal error: unknown section item: %s", item)
		}
	}
	if t.error != nil {
		return nil
	}
	s.end = t.elems.Len();
	return s;
}

func (t *Template) parse() {
	for t.error == nil {
		item := t.nextItem();
		if t.error != nil {
			break
		}
		if len(item) == 0 {
			break
		}
		done, tok, w := t.parseSimple(item);
		if done {
			continue
		}
		switch tok {
		case tokOr, tokEnd, tokAlternates:
			t.parseError("unexpected %s", w[0])
		case tokSection:
			t.parseSection(w)
		case tokRepeated:
			t.parseRepeated(w)
		default:
			t.parseError("internal error: bad directive in parse: %s", item)
		}
	}
}

// -- Execution

// If the data for this template is a struct, find the named variable.
// Names of the form a.b.c are walked down the data tree.
// The special name "@" (the "cursor") denotes the current data.
// The value coming in (st.data) might need indirecting to reach
// a struct while the return value is not indirected - that is,
// it represents the actual named field.
func (st *state) findVar(s string) reflect.Value {
	if s == "@" {
		return st.data
	}
	data := st.data;
	elems := strings.Split(s, ".", 0);
	for i := 0; i < len(elems); i++ {
		// Look up field; data must be a struct.
		data = reflect.Indirect(data);
		if data == nil {
			return nil
		}
		typ, ok := data.Type().(*reflect.StructType);
		if !ok {
			return nil
		}
		field, ok := typ.FieldByName(elems[i]);
		if !ok {
			return nil
		}
		data = data.(*reflect.StructValue).FieldByIndex(field.Index);
	}
	return data;
}

// Is there no data to look at?
func empty(v reflect.Value) bool {
	v = reflect.Indirect(v);
	if v == nil {
		return true
	}
	switch v := v.(type) {
	case *reflect.BoolValue:
		return v.Get() == false
	case *reflect.StringValue:
		return v.Get() == ""
	case *reflect.StructValue:
		return false
	case *reflect.ArrayValue:
		return v.Len() == 0
	case *reflect.SliceValue:
		return v.Len() == 0
	}
	return true;
}

// Look up a variable, up through the parent if necessary.
func (t *Template) varValue(name string, st *state) reflect.Value {
	field := st.findVar(name);
	if field == nil {
		if st.parent == nil {
			t.execError(st, t.linenum, "name not found: %s", name)
		}
		return t.varValue(name, st.parent);
	}
	return field;
}

// Evaluate a variable, looking up through the parent if necessary.
// If it has a formatter attached ({var|formatter}) run that too.
func (t *Template) writeVariable(v *variableElement, st *state) {
	formatter := v.formatter;
	val := t.varValue(v.name, st).Interface();
	// is it in user-supplied map?
	if t.fmap != nil {
		if fn, ok := t.fmap[formatter]; ok {
			fn(st.wr, val, formatter);
			return;
		}
	}
	// is it in builtin map?
	if fn, ok := builtins[formatter]; ok {
		fn(st.wr, val, formatter);
		return;
	}
	t.execError(st, v.linenum, "missing formatter %s for variable %s", formatter, v.name);
}

// Execute element i.  Return next index to execute.
func (t *Template) executeElement(i int, st *state) int {
	switch elem := t.elems.At(i).(type) {
	case *textElement:
		st.wr.Write(elem.text);
		return i + 1;
	case *literalElement:
		st.wr.Write(elem.text);
		return i + 1;
	case *variableElement:
		t.writeVariable(elem, st);
		return i + 1;
	case *sectionElement:
		t.executeSection(elem, st);
		return elem.end;
	case *repeatedElement:
		t.executeRepeated(elem, st);
		return elem.end;
	}
	e := t.elems.At(i);
	t.execError(st, 0, "internal error: bad directive in execute: %v %T\n", reflect.NewValue(e).Interface(), e);
	return 0;
}

// Execute the template.
func (t *Template) execute(start, end int, st *state) {
	for i := start; i < end; {
		i = t.executeElement(i, st)
	}
}

// Execute a .section
func (t *Template) executeSection(s *sectionElement, st *state) {
	// Find driver data for this section.  It must be in the current struct.
	field := t.varValue(s.field, st);
	if field == nil {
		t.execError(st, s.linenum, ".section: cannot find field %s in %s", s.field, reflect.Indirect(st.data).Type())
	}
	st = st.clone(field);
	start, end := s.start, s.or;
	if !empty(field) {
		// Execute the normal block.
		if end < 0 {
			end = s.end
		}
	} else {
		// Execute the .or block.  If it's missing, do nothing.
		start, end = s.or, s.end;
		if start < 0 {
			return
		}
	}
	for i := start; i < end; {
		i = t.executeElement(i, st)
	}
}

// Return the result of calling the Iter method on v, or nil.
func iter(v reflect.Value) *reflect.ChanValue {
	for j := 0; j < v.Type().NumMethod(); j++ {
		mth := v.Type().Method(j);
		fv := v.Method(j);
		ft := fv.Type().(*reflect.FuncType);
		// TODO(rsc): NumIn() should return 0 here, because ft is from a curried FuncValue.
		if mth.Name != "Iter" || ft.NumIn() != 1 || ft.NumOut() != 1 {
			continue
		}
		ct, ok := ft.Out(0).(*reflect.ChanType);
		if !ok || ct.Dir()&reflect.RecvDir == 0 {
			continue
		}
		return fv.Call(nil)[0].(*reflect.ChanValue);
	}
	return nil;
}

// Execute a .repeated section
func (t *Template) executeRepeated(r *repeatedElement, st *state) {
	// Find driver data for this section.  It must be in the current struct.
	field := t.varValue(r.field, st);
	if field == nil {
		t.execError(st, r.linenum, ".repeated: cannot find field %s in %s", r.field, reflect.Indirect(st.data).Type())
	}

	start, end := r.start, r.or;
	if end < 0 {
		end = r.end
	}
	if r.altstart >= 0 {
		end = r.altstart
	}
	first := true;

	if array, ok := field.(reflect.ArrayOrSliceValue); ok {
		for j := 0; j < array.Len(); j++ {
			newst := st.clone(array.Elem(j));

			// .alternates between elements
			if !first && r.altstart >= 0 {
				for i := r.altstart; i < r.altend; {
					i = t.executeElement(i, newst)
				}
			}
			first = false;

			for i := start; i < end; {
				i = t.executeElement(i, newst)
			}
		}
	} else if ch := iter(field); ch != nil {
		for {
			e := ch.Recv();
			if ch.Closed() {
				break
			}
			newst := st.clone(e);

			// .alternates between elements
			if !first && r.altstart >= 0 {
				for i := r.altstart; i < r.altend; {
					i = t.executeElement(i, newst)
				}
			}
			first = false;

			for i := start; i < end; {
				i = t.executeElement(i, newst)
			}
		}
	} else {
		t.execError(st, r.linenum, ".repeated: cannot repeat %s (type %s)",
			r.field, field.Type())
	}

	if first {
		// Empty. Execute the .or block, once.  If it's missing, do nothing.
		start, end := r.or, r.end;
		if start >= 0 {
			newst := st.clone(field);
			for i := start; i < end; {
				i = t.executeElement(i, newst)
			}
		}
		return;
	}
}

// A valid delimiter must contain no white space and be non-empty.
func validDelim(d []byte) bool {
	if len(d) == 0 {
		return false
	}
	for _, c := range d {
		if white(c) {
			return false
		}
	}
	return true;
}

// -- Public interface

// Parse initializes a Template by parsing its definition.  The string
// s contains the template text.  If any errors occur, Parse returns
// the error.
func (t *Template) Parse(s string) os.Error {
	if !validDelim(t.ldelim) || !validDelim(t.rdelim) {
		return &Error{1, fmt.Sprintf("bad delimiter strings %q %q", t.ldelim, t.rdelim)}
	}
	t.buf = strings.Bytes(s);
	t.p = 0;
	t.linenum = 1;
	t.parse();
	return t.error;
}

// Execute applies a parsed template to the specified data object,
// generating output to wr.
func (t *Template) Execute(data interface{}, wr io.Writer) os.Error {
	// Extract the driver data.
	val := reflect.NewValue(data);
	errors := make(chan os.Error);
	go func() {
		t.p = 0;
		t.execute(0, t.elems.Len(), &state{nil, val, wr, errors});
		errors <- nil;	// clean return;
	}();
	return <-errors;
}

// SetDelims sets the left and right delimiters for operations in the
// template.  They are validated during parsing.  They could be
// validated here but it's better to keep the routine simple.  The
// delimiters are very rarely invalid and Parse has the necessary
// error-handling interface already.
func (t *Template) SetDelims(left, right string) {
	t.ldelim = strings.Bytes(left);
	t.rdelim = strings.Bytes(right);
}

// Parse creates a Template with default parameters (such as {} for
// metacharacters).  The string s contains the template text while
// the formatter map fmap, which may be nil, defines auxiliary functions
// for formatting variables.  The template is returned. If any errors
// occur, err will be non-nil.
func Parse(s string, fmap FormatterMap) (t *Template, err os.Error) {
	t = New(fmap);
	err = t.Parse(s);
	if err != nil {
		t = nil
	}
	return;
}

// MustParse is like Parse but panics if the template cannot be parsed.
func MustParse(s string, fmap FormatterMap) *Template {
	t, err := Parse(s, fmap);
	if err != nil {
		panic("template parse error: ", err.String())
	}
	return t;
}
