part of mustache;

final RegExp _validTag = new RegExp(r'^[0-9a-zA-Z\_\-\.]+$');
final RegExp _integerTag = new RegExp(r'^[0-9]+$');

const Object _noSuchProperty = const Object();

class _RenderContext {
  
  _RenderContext(this._sink,
      List stack,
      this.lenient,
      this.htmlEscapeValues,
      this.partialResolver,
      this.templateName,
      this.indent,
      this.source)
    : _stack = new List.from(stack); 
  
  _RenderContext.partial(_RenderContext ctx, _Template partial, String indent)
      : this(ctx._sink,
          ctx._stack,
          ctx.lenient,
          ctx.htmlEscapeValues,
          ctx.partialResolver,
          ctx.templateName,
          ctx.indent + indent,
          partial.source);

  _RenderContext.subtree(_RenderContext ctx, StringSink sink)
     : this(sink,
         ctx._stack,
         ctx.lenient,
         ctx.htmlEscapeValues,
         ctx.partialResolver,
         ctx.templateName,
         ctx.indent,
         ctx.source);

    _RenderContext.lambda(
        _RenderContext ctx,
        String source,
        String indent,
        StringSink sink,
        String delimiters)
       : this(sink,
           ctx._stack,
           ctx.lenient,
           ctx.htmlEscapeValues,
           ctx.partialResolver,
           ctx.templateName,
           ctx.indent + indent,
           source);
   
  final StringSink _sink;
  final List _stack;
  final bool lenient;
  final bool htmlEscapeValues;
  final PartialResolver partialResolver;
  final String templateName;
  final String indent;
  final String source;

  void pushValue(value) => _stack.add(value);
  
  Object popValue() => _stack.removeLast();
  
  write(Object output) => _sink.write(output.toString());
    
  // Walks up the stack looking for the variable.
  // Handles dotted names of the form "a.b.c".
  Object resolveValue(String name) {
    if (name == '.') {
      return _stack.last;
    }
    var parts = name.split('.');
    var object = _noSuchProperty;
    for (var o in _stack.reversed) {
      object = _getNamedProperty(o, parts[0]);
      if (object != _noSuchProperty) {
        break;
      }
    }
    for (int i = 1; i < parts.length; i++) {
      if (object == null || object == _noSuchProperty) {
        return _noSuchProperty;
      }
      object = _getNamedProperty(object, parts[i]);
    }
    return object;
  }
  
  // Returns the property of the given object by name. For a map,
  // which contains the key name, this is object[name]. For other
  // objects, this is object.name or object.name(). If no property
  // by the given name exists, this method returns noSuchProperty.
  _getNamedProperty(object, name) {
    
    if (object is Map && object.containsKey(name))
      return object[name];
    
    if (object is List && _integerTag.hasMatch(name))
      return object[int.parse(name)];
    
    if (lenient && !_validTag.hasMatch(name))
      return _noSuchProperty;
    
    var instance = reflect(object);
    var field = instance.type.instanceMembers[new Symbol(name)];
    if (field == null) return _noSuchProperty;
    
    var invocation = null;
    if ((field is VariableMirror) || ((field is MethodMirror) && (field.isGetter))) {
      invocation = instance.getField(field.simpleName);
    } else if ((field is MethodMirror) && (field.parameters.length == 0)) {
      invocation = instance.invoke(field.simpleName, []);
    }
    if (invocation == null) {
      return _noSuchProperty;
    }
    return invocation.reflectee;
  }
  
  TemplateException error(String message, _Node node)
    => new _TemplateException(message, templateName, source, node.start);
}
