library mustache.parser;

import 'node.dart';
import 'scanner.dart';
import 'template_exception.dart';
import 'token.dart';

List<Node> parse(String source,
             bool lenient,
             String templateName,
             String delimiters) {
  var parser = new Parser(source, templateName, delimiters, lenient: lenient);
  return parser.parse();
}

class Tag {
  Tag(this.type, this.name, this.start, this.end);
  final TagType type;
  final String name;
  final int start;
  final int end;
}

class TagType {
  const TagType(this.name);
  final String name;
  
  static const TagType openSection = const TagType('openSection');
  static const TagType openInverseSection = const TagType('openInverseSection');
  static const TagType closeSection = const TagType('closeSection');
  static const TagType variable = const TagType('variable');
  static const TagType tripleMustache = const TagType('tripleMustache');
  static const TagType unescapedVariable = const TagType('unescapedVariable');
  static const TagType partial = const TagType('partial');
  static const TagType comment = const TagType('comment');
  static const TagType changeDelimiter = const TagType('changeDelimiter');
}


class Parser {
  
  Parser(String source, String templateName, String delimiters,
         {lenient: false})
      : _source = source,
        _templateName = templateName,
        _delimiters = delimiters,
        _lenient = lenient,
        _scanner = new Scanner(
            source, templateName, delimiters, lenient: lenient);
  
  final String _source;
  final bool _lenient;
  final String _templateName;
  final String _delimiters;  
  final Scanner _scanner;  
  final List<SectionNode> _stack = <SectionNode>[];
  List<Token> _tokens;
  String _currentDelimiters;  
  int _offset = 0;

  
  List<Node> parse() {
    
    _tokens = _scanner.scan();  
    _currentDelimiters = _delimiters;    
    _stack.clear();
    _stack.add(new SectionNode('root', 0, 0, _delimiters));    
  
    // Handle a standalone tag on first line, including special case where the
    // first line is empty.
    var lineEnd = _readIf(TokenType.lineEnd, eofOk: true);
    if (lineEnd != null) _appendTextToken(lineEnd);
    _parseLine();
    
    for (var token = _peek(); token != null; token = _peek()) {
      switch(token.type) {
        
        case TokenType.text:
        case TokenType.whitespace:            
            _read();
            _appendTextToken(token);
          break;
        
        case TokenType.openDelimiter:
          var tag = _readTag();
          var node = _createNodeFromTag(tag);
          if (tag != null) _appendTag(tag, node);
          break;
                 
        case TokenType.changeDelimiter:
          _read();
          _currentDelimiters = token.value;
          break;
          
        case TokenType.lineEnd:
          _appendTextToken(_read());
          _parseLine();
          break;
          
        default:
          throw new Exception('Unreachable code.');
      }
    }
    
    if (_stack.length != 1) {
      throw new TemplateException("Unclosed tag: '${_stack.last.name}'.",
          _templateName, _source, _stack.last.start);
    }
    
    return _stack.last.children;
  }
  
  // Returns null on EOF.
  Token _peek() => _offset < _tokens.length ? _tokens[_offset] : null;
  
  // Returns null on EOF.
  Token _read() {
    var t = null;
    if (_offset < _tokens.length) {
      t = _tokens[_offset];
      _offset++;
    }
    return t;
  }
      
  Token _expect(TokenType type) {
    var token = _read();
    if (token == null) throw _errorEof();
    if (token.type != type) {
      throw _error('Expected: ${type} found: ${token.type}.', _offset);
    }
    return token;
  }
  
  Token _readIf(TokenType type, {eofOk: false}) {
    var token = _peek();
    if (!eofOk && token == null) throw _errorEof();
    return token != null && token.type == type ? _read() : null;
  }
  
  TemplateException _errorEof() =>
      _error('Unexpected end of input.', _source.length - 1);
  
  TemplateException _error(String msg, int offset) => 
      new TemplateException(msg, _templateName, _source, offset);
  
  // Add a text node to top most section on the stack and merge consecutive
  // text nodes together.
  void _appendTextToken(Token token) {
    assert(const [TokenType.text, TokenType.lineEnd, TokenType.whitespace]
      .contains(token.type));
    var children = _stack.last.children;
    if (children.isEmpty || children.last is! TextNode) {
      children.add(new TextNode(token.value, token.start, token.end));
    } else {
      var last = children.removeLast();
      var node = new TextNode(last.text + token.value, last.start, token.end);
      children.add(node);
    }
  }
  
  // Add the node to top most section on the stack. If a section node then
  // push it onto the stack, if a close section tag, then pop the stack.
  void _appendTag(Tag tag, Node node) {
    switch (tag.type) {
      
      // {{#...}}  {{^...}}
      case TagType.openSection:
      case TagType.openInverseSection:
        _stack.last.children.add(node);
        _stack.add(node);
        break;
        
      // {{/...}}
      case TagType.closeSection:
        if (tag.name != _stack.last.name) {
          throw new TemplateException("Mismatched tag, expected: "
              "'${_stack.last.name}', was: '${tag.name}'",
              _templateName, _source, tag.start);
        }
        var node = _stack.removeLast();
        node.contentEnd = tag.start;
        break;        
      
      // {{...}} {{&...}} {{{...}}}
      case TagType.variable:
      case TagType.unescapedVariable:
      case TagType.tripleMustache:
      case TagType.partial:
        if (node != null) _stack.last.children.add(node);
        break;
      
      case TagType.comment:
      case TagType.changeDelimiter:
        // Ignore.
        break;

      default:
        throw new Exception('Unreachable code.');
    }
  }
    
  // Handle standalone tags and indented partials.
  //
  // A "standalone tag" in the spec is a tag one a line where the line only
  // contains whitespace. During rendering the whitespace is ommitted.
  // Standalone partials also indent their content to match the tag during 
  // rendering.
  
  // match:
  // lineEnd whitespace openDelimiter any* closeDelimiter whitespace lineEnd
  //
  // Where lineEnd can also mean start/end of the source.
  void _parseLine() {   
    // Continue parsing standalone lines until we find one than isn't a
    // standalone line.        
    while (_peek() != null) {
      var precedingLineEnd = _readIf(TokenType.lineEnd, eofOk: true);
      var precedingWhitespace = _readIf(TokenType.whitespace, eofOk: true);          
      var indent = precedingWhitespace == null ? '' : precedingWhitespace.value;
      var tag = _readTag();
      var tagNode = _createNodeFromTag(tag, partialIndent: indent);
      var followingWhitespace = _readIf(TokenType.whitespace, eofOk: true);
      
      const standaloneTypes = const [
        TagType.openSection,
        TagType.closeSection,
        TagType.openInverseSection,
        TagType.partial,
        TagType.comment,
        TagType.changeDelimiter]; 
      
      if (tag != null &&
          (_peek() == null || _peek().type == TokenType.lineEnd) &&
          standaloneTypes.contains(tag.type)) {                
        // This is a tag on a "standalone line", so do not create text nodes
        // for whitespace, or the following newline.
        _appendTag(tag, tagNode);
        // Now continue to loop and parse the next line.
      } else {
        // This is not a standalone line so add the whitespace to the ast.        
        if (precedingWhitespace != null) _appendTextToken(precedingWhitespace);
        if (tag != null) _appendTag(tag, tagNode);
        if (followingWhitespace != null) _appendTextToken(followingWhitespace);        
        // Done parsing standalone lines. Exit the loop.
        break;
      }
    }
  }
  
  final RegExp _validIdentifier = new RegExp(r'^[0-9a-zA-Z\_\-\.]+$');
  
  static const _tagTypeMap = const {
          '#': TagType.openSection,
          '^': TagType.openInverseSection,
          '/': TagType.closeSection,
          '&': TagType.unescapedVariable,
          '>': TagType.partial,
          '!': TagType.comment};

  // If open delimiter, or change delimiter token then return a tag.
  // If EOF or any another token then return null.
  Tag _readTag() {
    
    var t = _peek();
    if (t == null ||
        (t.type != TokenType.changeDelimiter &&
         t.type != TokenType.openDelimiter)) {
      return null;
    
    } else if (t.type == TokenType.changeDelimiter) {      
      _read();
      // Remember the current delimiters.
      _currentDelimiters = t.value;
      
      // Change delimiter tags are already parsed by the scanner.
      // So just create a tag and return it.
      return new Tag(TagType.changeDelimiter, t.value, t.start, t.end);
    }
    
    // Start parsing a typical tag.
    
    var open = _expect(TokenType.openDelimiter);
    
    _readIf(TokenType.whitespace);
    
    // A sigil is the character which identifies which sort of tag it is,
    // i.e.  '#', '/', or '>'.
    // Variable tags and triple mustache tags don't have a sigil.
    TagType tagType;
    
    if (open.value == '{{{') {
      tagType = TagType.tripleMustache;
    } else {
      var sigil = _readIf(TokenType.sigil);
      tagType = sigil == null ? TagType.variable : _tagTypeMap[sigil.value];
    }
      
    _readIf(TokenType.whitespace);
    
    // TODO split up names here instead of during render.
    // Also check that they are valid token types.
    // TODO split up names here instead of during render.
    // Also check that they are valid token types.     
    var list = <Token>[];
    for (var t = _peek();
         t != null && t.type != TokenType.closeDelimiter; t = _peek()) {
      _read();
      list.add(t);
    }    
    var name = list.map((t) => t.value).join().trim();
    if (_peek() == null) throw _errorEof();
    
    // Check to see if the tag name is valid.
    if (tagType != TagType.comment) {    
      if (name == '') throw _error('Empty tag name.', open.start);      
      if (!_lenient) {
        if (name.contains('\t') || name.contains('\n') || name.contains('\r')) {
          throw _error('Tags may not contain newlines or tabs.', open.start);
        }    
        
        if (!_validIdentifier.hasMatch(name)) {
          throw _error('Unless in lenient mode, tags may only contain the '
              'characters a-z, A-Z, minus, underscore and period.', open.start);
        }
      }
    }
    
    var close = _expect(TokenType.closeDelimiter);
        
    return new Tag(tagType, name, open.start, close.end);
  }
  
  Node _createNodeFromTag(Tag tag, {String partialIndent: ''}) {
    // Handle EOF case.
    if (tag == null) return null;
    
    Node node = null;
    switch (tag.type) {
      
      case TagType.openSection:
      case TagType.openInverseSection:
        bool inverse = tag.type == TagType.openInverseSection;
        node = new SectionNode(tag.name, tag.start, tag.end, 
          _currentDelimiters, inverse: inverse);
        break;
   
      case TagType.variable:
      case TagType.unescapedVariable:
      case TagType.tripleMustache:
        bool escape = tag.type == TagType.variable;
        node = new VariableNode(tag.name, tag.start, tag.end, escape: escape);
        break;
        
      case TagType.partial:
        node = new PartialNode(tag.name, tag.start, tag.end, partialIndent);
        break;
            
      case TagType.closeSection:
      case TagType.comment:
      case TagType.changeDelimiter:
        node = null;
        break;

      default:
        throw new Exception('Unreachable code');
    }
    return node;
  }  
}
