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);

  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() as TextNode;
      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 omitted.
  // 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() {
    // If first token is a newline append it.
    var t = _peek();
    if (t != null && t.type == TokenType.lineEnd) _appendTextToken(t);

    // Continue parsing standalone lines until we find one than isn't a
    // standalone line.
    while (_peek() != null) {
      _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;
  }
}
