// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class Tokenizer extends TokenizerBase {
  TokenKind tmplTokens;

  bool _selectorParsing;

  Tokenizer(SourceFile source, bool skipWhitespace, [int index = 0])
    : super(source, skipWhitespace, index), _selectorParsing = false {
      tmplTokens = new TokenKind();
  }

  int get startIndex => _startIndex;
  void set index(int idx) {
    _index = idx;
  }

  Token next([bool inTag = true]) {
    // keep track of our starting position
    _startIndex = _index;

    if (_interpStack != null && _interpStack.depth == 0) {
      var istack = _interpStack;
      _interpStack = _interpStack.pop();

      /* TODO(terry): Enable for variable and string interpolation.
       * if (istack.isMultiline) {
       *   return finishMultilineStringBody(istack.quote);
       * } else {
       *   return finishStringBody(istack.quote);
       * }
       */
    }

    int ch;
    ch = _nextChar();
    switch(ch) {
      case 0:
        return _finishToken(TokenKind.END_OF_FILE);
      case tmplTokens.tokens[TokenKind.SPACE]:
      case tmplTokens.tokens[TokenKind.TAB]:
      case tmplTokens.tokens[TokenKind.NEWLINE]:
      case tmplTokens.tokens[TokenKind.RETURN]:
        if (inTag) {
          return finishWhitespace();
        } else {
          return _finishToken(TokenKind.WHITESPACE);
        }
      case tmplTokens.tokens[TokenKind.END_OF_FILE]:
        return _finishToken(TokenKind.END_OF_FILE);
      case tmplTokens.tokens[TokenKind.LPAREN]:
        return _finishToken(TokenKind.LPAREN);
      case tmplTokens.tokens[TokenKind.RPAREN]:
        return _finishToken(TokenKind.RPAREN);
      case tmplTokens.tokens[TokenKind.COMMA]:
        return _finishToken(TokenKind.COMMA);
      case tmplTokens.tokens[TokenKind.LBRACE]:
        return _finishToken(TokenKind.LBRACE);
      case tmplTokens.tokens[TokenKind.RBRACE]:
        return _finishToken(TokenKind.RBRACE);
      case tmplTokens.tokens[TokenKind.LESS_THAN]:
        return _finishToken(TokenKind.LESS_THAN);
      case tmplTokens.tokens[TokenKind.GREATER_THAN]:
        return _finishToken(TokenKind.GREATER_THAN);
      case tmplTokens.tokens[TokenKind.EQUAL]:
        if (inTag) {
          if (_maybeEatChar(tmplTokens.tokens[TokenKind.SINGLE_QUOTE])) {
            return finishQuotedAttrValue(
              tmplTokens.tokens[TokenKind.SINGLE_QUOTE]);
          } else if (_maybeEatChar(tmplTokens.tokens[TokenKind.DOUBLE_QUOTE])) {
            return finishQuotedAttrValue(
              tmplTokens.tokens[TokenKind.DOUBLE_QUOTE]);
          } else if (TokenizerHelpers.isAttributeValueStart(_peekChar())) {
            return finishAttrValue();
          }
        }
        return _finishToken(TokenKind.EQUAL);
      case tmplTokens.tokens[TokenKind.SLASH]:
        if (_maybeEatChar(tmplTokens.tokens[TokenKind.GREATER_THAN])) {
          return _finishToken(TokenKind.END_NO_SCOPE_TAG);          // />
        } else if (_maybeEatChar(tmplTokens.tokens[TokenKind.ASTERISK])) {
          return finishMultiLineComment();
        } else {
          return _finishToken(TokenKind.SLASH);
        }
      case tmplTokens.tokens[TokenKind.DOLLAR]:
        if (_maybeEatChar(tmplTokens.tokens[TokenKind.LBRACE])) {
          if (_maybeEatChar(tmplTokens.tokens[TokenKind.HASH])) {
            return _finishToken(TokenKind.START_COMMAND);           // ${#
          } else if (_maybeEatChar(tmplTokens.tokens[TokenKind.SLASH])) {
            return _finishToken(TokenKind.END_COMMAND);             // ${/
          } else {
            return _finishToken(TokenKind.START_EXPRESSION);        // ${
          }
        } else {
          return _finishToken(TokenKind.DOLLAR);
        }

      default:
        if (TokenizerHelpers.isIdentifierStart(ch)) {
          return this.finishIdentifier();
        } else if (TokenizerHelpers.isDigit(ch)) {
          return this.finishNumber();
        } else {
          return _errorToken();
        }
    }
  }

  // TODO(jmesserly): we need a way to emit human readable error messages from
  // the tokenizer.
  Token _errorToken([String message = null]) {
    return _finishToken(TokenKind.ERROR);
  }

  int getIdentifierKind() {
    // Is the identifier an element?
    int tokId = TokenKind.matchElements(_text, _startIndex,
      _index - _startIndex);
    if (tokId == -1) {
      // No, is it an attribute?
//      tokId = TokenKind.matchAttributes(_text, _startIndex, _index - _startIndex);
    }
    if (tokId == -1) {
      tokId = TokenKind.matchKeywords(_text, _startIndex, _index - _startIndex);
    }

    return tokId >= 0 ? tokId : TokenKind.IDENTIFIER;
  }

  // Need to override so CSS version of isIdentifierPart is used.
  Token finishIdentifier() {
    while (_index < _text.length) {
//      if (!TokenizerHelpers.isIdentifierPart(_text.codeUnitAt(_index++))) {
      if (!TokenizerHelpers.isIdentifierPart(_text.codeUnitAt(_index))) {
//        _index--;
        break;
      } else {
        _index += 1;
      }
    }
    if (_interpStack != null && _interpStack.depth == -1) {
      _interpStack.depth = 0;
    }
    int kind = getIdentifierKind();
    if (kind == TokenKind.IDENTIFIER) {
      return _finishToken(TokenKind.IDENTIFIER);
    } else {
      return _finishToken(kind);
    }
  }

  Token _makeAttributeValueToken(List<int> buf) {
    final s = new String.fromCharCodes(buf);
    return new LiteralToken(TokenKind.ATTR_VALUE, _source, _startIndex, _index,
      s);
  }

  /* quote if -1 signals to read upto first whitespace otherwise read upto
   * single or double quote char.
   */
  Token finishQuotedAttrValue([int quote = -1]) {
    var buf = new List<int>();
    while (true) {
      int ch = _nextChar();
      if (ch == quote) {
        return _makeAttributeValueToken(buf);
      } else if (ch == 0) {
        return _errorToken();
      } else {
        buf.add(ch);
      }
    }
  }

  Token finishAttrValue() {
    var buf = new List<int>();
    while (true) {
      int ch = _peekChar();
      if (TokenizerHelpers.isWhitespace(ch) || TokenizerHelpers.isSlash(ch) ||
          TokenizerHelpers.isCloseTag(ch)) {
        return _makeAttributeValueToken(buf);
      } else if (ch == 0) {
        return _errorToken();
      } else {
        buf.add(_nextChar());
      }
    }
  }

  Token finishNumber() {
    eatDigits();

    if (_peekChar() == 46/*.*/) {
      // Handle the case of 1.toString().
      _nextChar();
      if (TokenizerHelpers.isDigit(_peekChar())) {
        eatDigits();
        return _finishToken(TokenKind.DOUBLE);
      } else {
        _index -= 1;
      }
    }

    return _finishToken(TokenKind.INTEGER);
  }

  bool maybeEatDigit() {
    if (_index < _text.length && TokenizerHelpers.isDigit(
        _text.codeUnitAt(_index))) {
      _index += 1;
      return true;
    }
    return false;
  }

  void eatHexDigits() {
    while (_index < _text.length) {
     if (TokenizerHelpers.isHexDigit(_text.codeUnitAt(_index))) {
       _index += 1;
     } else {
       return;
     }
    }
  }

  bool maybeEatHexDigit() {
    if (_index < _text.length && TokenizerHelpers.isHexDigit(
        _text.codeUnitAt(_index))) {
      _index += 1;
      return true;
    }
    return false;
  }

  Token finishMultiLineComment() {
    while (true) {
      int ch = _nextChar();
      if (ch == 0) {
        return _finishToken(TokenKind.INCOMPLETE_COMMENT);
      } else if (ch == 42/*'*'*/) {
        if (_maybeEatChar(47/*'/'*/)) {
          if (_skipWhitespace) {
            return next();
          } else {
            return _finishToken(TokenKind.COMMENT);
          }
        }
      } else if (ch == tmplTokens.tokens[TokenKind.MINUS]) {
        /* Check if close part of Comment Definition --> (CDC). */
        if (_maybeEatChar(tmplTokens.tokens[TokenKind.MINUS])) {
          if (_maybeEatChar(tmplTokens.tokens[TokenKind.GREATER_THAN])) {
            if (_skipWhitespace) {
              return next();
            } else {
              return _finishToken(TokenKind.HTML_COMMENT);
            }
          }
        }
      }
    }
    return _errorToken();
  }

}


/** Static helper methods. */
class TokenizerHelpers {
  static bool isIdentifierStart(int c) {
    return ((c >= 97/*a*/ && c <= 122/*z*/) ||
        (c >= 65/*A*/ && c <= 90/*Z*/) || c == 95/*_*/);
  }

  static bool isDigit(int c) {
    return (c >= 48/*0*/ && c <= 57/*9*/);
  }

  static bool isHexDigit(int c) {
    return (isDigit(c) || (c >= 97/*a*/ && c <= 102/*f*/) ||
        (c >= 65/*A*/ && c <= 70/*F*/));
  }

  static bool isWhitespace(int c) {
    return (c == 32/*' '*/ || c == 9/*'\t'*/ || c == 10/*'\n'*/ ||
        c == 13/*'\r'*/);
  }

  static bool isIdentifierPart(int c) {
    return (isIdentifierStart(c) || isDigit(c) || c == 45/*-*/ ||
        c == 58/*:*/ || c == 46/*.*/);
  }

  static bool isInterpIdentifierPart(int c) {
    return (isIdentifierStart(c) || isDigit(c));
  }

  static bool isAttributeValueStart(int c) {
    return !isWhitespace(c) && !isSlash(c) && !isCloseTag(c);
  }

  static bool isSlash(int c) {
    return (c == 47/* / */);
  }

  static bool isCloseTag(int c) {
    return (c == 62/* > */);
  }
}
