part of mustache.impl;

List<Node> parse(String source,
             bool lenient,
             String templateName,
             String delimiters) {
  
  if (source == null) throw new ArgumentError.notNull('Template source');
  
  var tokens = 
      new Scanner(source, templateName, delimiters, lenient: lenient).scan();
  
  tokens = _removeStandaloneWhitespace(tokens);
  tokens = _mergeAdjacentText(tokens);
  
  var stack = new List<Node>()..add(new _SectionNode('root', 0, 0, delimiters));

  var delim;
  
  for (var t in tokens) {
    switch (t.type) {
      case _TEXT:
        var n = new _TextNode(t.value, t.start, t.end);
        stack.last.children.add(n);
        break;
        
      case _VARIABLE:
      case _UNESC_VARIABLE:
        var n = new _VariableNode(
            t.value, t.start, t.end, escape: t.type != _UNESC_VARIABLE);
        stack.last.children.add(n);
        break;

      case _PARTIAL:
        var n = new _PartialNode(t.value, t.start, t.end, t.indent); 
        stack.last.children.add(n);
        break;

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

      case _CLOSE_SECTION:
        if (stack.last.name != t.value) {
          throw new _TemplateException(
            "Mismatched tag, expected: '${stack.last.name}', was: '${t.value}'",
            templateName, source, t.start);
        }
  
        stack.last.contentEnd = t.start;
        
        stack.removeLast();
        break;
      
      case _CHANGE_DELIMITER:
        delim = t.value;
        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');
    }
  }

  if (stack.length != 1) {
    throw new _TemplateException(
      "Unclosed tag: '${stack.last.name}'.",
      templateName, source, stack.last.start);
  }
  
  return stack.last.children;
}

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