// Copyright (c) 2015, 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.

import 'dart:collection';

import 'package:analyzer/dart/ast/ast.dart';

// ASCII character codes.

const _zero = 0x30;
const _nine = 0x39;
const _backslash = 0x5C;
const _openCurly = 0x7B;
const _closeCurly = 0x7D;
const _capitalA = 0x41;
const _capitalZ = 0x5A;
const _a = 0x61;
const _n = 0x6E;
const _r = 0x72;
const _f = 0x66;
const _b = 0x62;
const _t = 0x74;
const _u = 0x75;
const _v = 0x76;
const _x = 0x78;
const _z = 0x7A;
const _newline = 0xA;
const _carriageReturn = 0xD;
const _formFeed = 0xC;
const _backspace = 0x8;
const _tab = 0x9;
const _verticalTab = 0xB;

/// An iterator over the runes in the value of a [StringLiteral].
///
/// In addition to exposing the values of the runes themselves, this also
/// exposes the offset of the current rune in the Dart source file.
class StringLiteralIterator extends Iterator<int> {
  int get current => _current;
  int _current;

  /// The offset of the beginning of [current] in the Dart source file that
  /// contains the string literal.
  ///
  /// Before iteration begins, this points to the character before the first
  /// rune.
  int get offset => _offset;
  int _offset;

  /// The offset of the next rune.
  ///
  /// This isn't necessarily just `offset + 1`, since a single rune may be
  /// represented by multiple characters in the source file, or a string literal
  /// may be composed of several adjacent string literals.
  int _nextOffset;

  /// All [SimpleStringLiteral]s that compose the input literal.
  ///
  /// If the input literal is itself a [SimpleStringLiteral], this just contains
  /// that literal; otherwise, the literal is an [AdjacentStrings], and this
  /// contains its component literals.
  final _strings = Queue<SimpleStringLiteral>();

  /// Whether this is a raw string that begins with `r`.
  ///
  /// This is necessary for knowing how to parse escape sequences.
  bool _isRaw;

  /// The iterator over the runes in the Dart source file.
  ///
  /// When switching to a new string in [_strings], this is updated to point to
  /// that string's component runes.
  Iterator<int> _runes;

  /// Creates a new [StringLiteralIterator] iterating over the contents of
  /// [literal].
  ///
  /// Throws an [ArgumentError] if [literal] contains interpolated strings.
  StringLiteralIterator(StringLiteral literal) {
    if (literal is StringInterpolation) {
      throw ArgumentError("Can't iterate over an interpolated string.");
    } else if (literal is SimpleStringLiteral) {
      _strings.add(literal);
    } else {
      assert(literal is AdjacentStrings);

      for (var string in (literal as AdjacentStrings).strings) {
        if (string is StringInterpolation) {
          throw ArgumentError("Can't iterate over an interpolated string.");
        }
        _strings.add(string as SimpleStringLiteral);
      }
    }

    _offset = _strings.first.contentsOffset - 1;
  }

  bool moveNext() {
    // If we're at beginning of a [SimpleStringLiteral], move forward until
    // there's actually text to consume.
    while (_runes == null || _runes.current == null) {
      if (_strings.isEmpty) {
        // Move the offset past the end of the text.
        _offset = _nextOffset;
        _current = null;
        return false;
      }

      var string = _strings.removeFirst();
      var start = string.contentsOffset - string.offset;

      // Compensate for the opening and closing quotes.
      var end = start +
          string.literal.lexeme.length -
          2 * (string.isMultiline ? 3 : 1) -
          (string.isRaw ? 1 : 0);
      var text = string.literal.lexeme.substring(start, end);

      _nextOffset = string.contentsOffset;
      _isRaw = string.isRaw;
      _runes = text.runes.iterator;
      _runes.moveNext();
    }

    _offset = _nextOffset;
    _current = _nextRune();
    if (_current != null) return true;

    // If we encounter a parse failure, stop moving forward immediately.
    _strings.clear();
    return false;
  }

  /// Consume and return the next rune.
  int _nextRune() {
    if (_isRaw || _runes.current != _backslash) {
      var rune = _runes.current;
      _moveRunesNext();
      return rune;
    }

    if (!_moveRunesNext()) return null;
    return _parseEscapeSequence();
  }

  /// Parse an escape sequence in the underlying Dart text.
  ///
  /// This assumes that a backslash has already been consumed. It leaves the
  /// [_runes] cursor on the first character after the escape sequence.
  int _parseEscapeSequence() {
    switch (_runes.current) {
      case _n:
        _moveRunesNext();
        return _newline;
      case _r:
        _moveRunesNext();
        return _carriageReturn;
      case _f:
        _moveRunesNext();
        return _formFeed;
      case _b:
        _moveRunesNext();
        return _backspace;
      case _t:
        _moveRunesNext();
        return _tab;
      case _v:
        _moveRunesNext();
        return _verticalTab;
      case _x:
        if (!_moveRunesNext()) return null;
        return _parseHex(2);
      case _u:
        if (!_moveRunesNext()) return null;
        if (_runes.current != _openCurly) return _parseHex(4);
        if (!_moveRunesNext()) return null;

        var number = _parseHexSequence();
        if (_runes.current != _closeCurly) return null;
        if (!_moveRunesNext()) return null;
        return number;
      default:
        var rune = _runes.current;
        _moveRunesNext();
        return rune;
    }
  }

  /// Parse a variable-length sequence of hexadecimal digits and returns their
  /// value as an [int].
  ///
  /// This parses digits as they appear in a unicode escape sequence: one to six
  /// hex digits.
  int _parseHexSequence() {
    var number = _parseHexDigit(_runes.current);
    if (number == null) return null;
    if (!_moveRunesNext()) return null;

    for (var i = 0; i < 5; i++) {
      var digit = _parseHexDigit(_runes.current);
      if (digit == null) break;
      number = number * 16 + digit;
      if (!_moveRunesNext()) return null;
    }

    return number;
  }

  /// Parses [digits] hexadecimal digits and returns their value as an [int].
  int _parseHex(int digits) {
    var number = 0;
    for (var i = 0; i < digits; i++) {
      if (_runes.current == null) return null;
      var digit = _parseHexDigit(_runes.current);
      if (digit == null) return null;
      number = number * 16 + digit;
      _moveRunesNext();
    }
    return number;
  }

  /// Parses a single hexadecimal digit.
  int _parseHexDigit(int rune) {
    if (rune < _zero) return null;
    if (rune <= _nine) return rune - _zero;
    if (rune < _capitalA) return null;
    if (rune <= _capitalZ) return 10 + rune - _capitalA;
    if (rune < _a) return null;
    if (rune <= _z) return 10 + rune - _a;
    return null;
  }

  /// Move [_runes] to the next rune and update [_nextOffset].
  bool _moveRunesNext() {
    var result = _runes.moveNext();
    _nextOffset++;
    return result;
  }
}
