// 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
	errors	chan os.Error;	// for error reporting 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.errors = make(chan os.Error);
	t.elems = vector.New(0);
	return t;
}

// Generic error handler, called only from execError or parseError.
func error(errors chan os.Error, line int, err string, args ...) {
	errors <- &Error{line, fmt.Sprintf(err, args)};
	runtime.Goexit();
}

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

// Report error and stop parsing.  The line number comes from the template state.
func (t *Template) parseError(err string, args ...) {
	error(t.errors, t.linenum, 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")
			}
			sawLeft = false;
			i += len(t.rdelim);
			break Loop;
		default:
			only_white = false;
		}
	}
	if sawLeft {
		t.parseError("unmatched opening delimiter")
	}
	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' {
				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
	}
	if len(item) <= len(t.ldelim)+len(t.rdelim) {	// no contents
		t.parseError("empty directive")
	}
	// 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")
	}
	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)
		}
		tok = tokSection;
		return;
	case ".repeated":
		if len(w) != 3 || w[1] != "section" {
			t.parseError("incorrect fields for .repeated: %s", item)
		}
		tok = tokRepeated;
		return;
	case ".alternates":
		if len(w) != 2 || w[1] != "with" {
			t.parseError("incorrect fields for .alternates: %s", item)
		}
		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);
	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;
	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 {
		item := t.nextItem();
		if len(item) ==  0 {
			t.parseError("missing .end for .repeated section")
		}
		done, tok, w := t.parseSimple(item);
		if done {
			continue
		}
		switch tok {
		case tokEnd:
			break Loop;
		case tokOr:
			if r.or >= 0 {
				t.parseError("extra .or in .repeated section");
			}
			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");
			}
			if r.or >= 0 {
				t.parseError(".alternates inside .or block in .repeated section");
			}
			r.altstart = t.elems.Len();
		default:
			t.parseError("internal error: unknown repeated section item: %s", item);
		}
	}
	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 {
		item := t.nextItem();
		if len(item) ==  0 {
			t.parseError("missing .end for .section")
		}
		done, tok, w := t.parseSimple(item);
		if done {
			continue
		}
		switch tok {
		case tokEnd:
			break Loop;
		case tokOr:
			if s.or >= 0 {
				t.parseError("extra .or in .section");
			}
			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);
		}
	}
	s.end = t.elems.Len();
	return s;
}

func (t *Template) parse() {
	for {
		item := t.nextItem();
		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 = 0;
	go func() {
		t.parse();
		t.errors <- nil;	// clean return;
	}();
	return <-t.errors;
}

// 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);
	return
}
