part of mustache;

_Node _parse(String source,
             bool lenient,
             String templateName,
             String delimiters,
             Map<String,LambdaFunction> helpers) {
  
  if (source == null) throw new ArgumentError('Template source is null');
  
  var tokens = 
      new _Scanner(source, templateName, delimiters, lenient: lenient).scan();
  
  tokens = _removeStandaloneWhitespace(tokens);
  tokens = _mergeAdjacentText(tokens);
  
  var stack = new List<_Node>()..add(new _Node(_OPEN_SECTION, 'root', 0, 0));

  for (var t in tokens) {
    switch (t.type) {
      case _TEXT:
      case _VARIABLE:
      case _UNESC_VARIABLE:
      case _PARTIAL:
        stack.last.children.add(new _Node.fromToken(t));
        break;

      case _OPEN_SECTION:
      case _OPEN_INV_SECTION:
        // Store the start, end of the inner string content not
        // including the tag.
        var child = new _Node.fromToken(t)..contentStart = t.end;
        stack.last.children.add(child);
        stack.add(child);
        break;

      case _CLOSE_SECTION:
        
        if (stack.last.value != t.value) {
          //FIXME quick hack for experimental helpers support.
          var helperName = t.value.split(new RegExp('[ \n\r\t]+')).first;
          if (helpers == null || !helpers.containsKey(helperName)) {
            throw new _TemplateException(
              "Mismatched tag, expected: '${stack.last.value}', was: '${t.value}'",
              templateName, source, t.start);
          }
        }
  
        stack.last.contentEnd = t.start;
        stack.removeLast();
        break;
      
      case _CHANGE_DELIMITER:
        stack.last.children.add(new _Node.fromToken(t));
        break;
        
      case _COMMENT:
        // Do nothing
        break;
      
      //FIXME change constants to enums, and then remove this default clause.
      default:
        throw new StateError('Unkown node type: $t');
    }
  }

  return stack.last;
}

// Takes a list of tokens, and removes _NEWLINE, and _WHITESPACE tokens.
// This is used to implement mustache standalone lines.
// Where TAG is one of: OPEN_SECTION, INV_SECTION, CLOSE_SECTION
// LINE_END, [WHITESPACE], TAG, [WHITESPACE], LINE_END => LINE_END, TAG
// WHITESPACE => TEXT
// LINE_END => TEXT
// TODO could rewrite this to use a generator, rather than creating an inter-
// mediate list.
List<_Token> _removeStandaloneWhitespace(List<_Token> tokens) {
  int i = 0;
  _Token read() { var ret = i < tokens.length ? tokens[i++] : null; return ret; }
  _Token peek([int n = 0]) => i + n < tokens.length ? tokens[i + n] : null;

  bool isTag(token) => token != null
      && const [_OPEN_SECTION, _OPEN_INV_SECTION, _CLOSE_SECTION, _COMMENT,
                _PARTIAL, _CHANGE_DELIMITER].contains(token.type);

  bool isWhitespace(token) => token != null && token.type == _WHITESPACE;
  bool isLineEnd(token) => token != null && token.type == _LINE_END;

  var result = new List<_Token>();
  add(token) => result.add(token);

  standaloneLineCheck() {
    // Swallow leading whitespace 
    // Note, the scanner will only ever create a single whitespace token. There
    // is no need to handle multiple whitespace tokens.
    if (isWhitespace(peek())
        && isTag(peek(1))
        && (isLineEnd(peek(2)) || peek(2) == null)) { // null == EOF
      read();
    } else if (isWhitespace(peek())
        && isTag(peek(1))
        && isWhitespace(peek(2))
        && (isLineEnd(peek(3)) || peek(3) == null)) {
      read();
    }

    if ((isTag(peek()) && isLineEnd(peek(1)))
        || (isTag(peek()) 
            && isWhitespace(peek(1))
            && (isLineEnd(peek(2)) || peek(2) == null))) {      

      // Add tag
      add(read());

      // Swallow trailing whitespace.
      if (isWhitespace(peek()))
        read();

      // Swallow line end.
      assert(isLineEnd(peek()));
      read();

      standaloneLineCheck(); //FIXME don't use recursion.
    }
  }

  // Handle case where first line is a standalone tag.
  standaloneLineCheck();

  var t;
  while ((t = read()) != null) {
    if (t.type == _LINE_END) {
      // Convert line end to text token
      add(new _Token(_TEXT, t.value, t.start, t.end));
      standaloneLineCheck();
    } else if (t.type == _WHITESPACE) {
      // Convert whitespace to text token
      add(new _Token(_TEXT, t.value, t.start, t.end));
    } else {
      // Preserve token
      add(t);
    }
  }

  return result;
}

// Merging adjacent text nodes will improve the render speed, but slow down
// parsing. It will be beneficial where templates are parsed once and rendered
// a number of times.
List<_Token> _mergeAdjacentText(List<_Token> tokens) {
  if (tokens.isEmpty) return <_Token>[];
  
  var result = new List<_Token>();
  int i = 0;
  while(i < tokens.length) {
    var t = tokens[i];
    
    if (t.type != _TEXT
        || (i < tokens.length - 1 && tokens[i + 1].type != _TEXT)) {
      result.add(tokens[i]);
      i++;
    } else {
      var buffer = new StringBuffer();
      while(i < tokens.length && tokens[i].type == _TEXT) {
        buffer.write(tokens[i].value);
        i++;
      }
      result.add(new _Token(_TEXT, buffer.toString(), t.start, t.end));
    }
  }
  return result;
}
