// 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 'charcode.dart';
import 'line_scanner.dart';
import 'span_scanner.dart';

// TODO(nweiz): Currently this duplicates code in line_scanner.dart. Once
// sdk#23770 is fully complete, we should move the shared code into a mixin.

/// A regular expression matching newlines across platforms.
final _newlineRegExp = RegExp(r'\r\n?|\n');

/// A [SpanScanner] that tracks the line and column eagerly, like [LineScanner].
class EagerSpanScanner extends SpanScanner {
  @override
  int get line => _line;
  int _line = 0;

  @override
  int get column => _column;
  int _column = 0;

  @override
  LineScannerState get state =>
      _EagerSpanScannerState(this, position, line, column);

  bool get _betweenCRLF => peekChar(-1) == $cr && peekChar() == $lf;

  @override
  set state(LineScannerState state) {
    if (state is! _EagerSpanScannerState || !identical(state._scanner, this)) {
      throw ArgumentError('The given LineScannerState was not returned by '
          'this LineScanner.');
    }

    super.position = state.position;
    _line = state.line;
    _column = state.column;
  }

  @override
  set position(int newPosition) {
    final oldPosition = position;
    super.position = newPosition;

    if (newPosition > oldPosition) {
      final newlines = _newlinesIn(string.substring(oldPosition, newPosition));
      _line += newlines.length;
      if (newlines.isEmpty) {
        _column += newPosition - oldPosition;
      } else {
        _column = newPosition - newlines.last.end;
      }
    } else {
      final newlines = _newlinesIn(string.substring(newPosition, oldPosition));
      if (_betweenCRLF) newlines.removeLast();

      _line -= newlines.length;
      if (newlines.isEmpty) {
        _column -= oldPosition - newPosition;
      } else {
        _column =
            newPosition - string.lastIndexOf(_newlineRegExp, newPosition) - 1;
      }
    }
  }

  EagerSpanScanner(String string, {sourceUrl, int? position})
      : super(string, sourceUrl: sourceUrl, position: position);

  @override
  bool scanChar(int character) {
    if (!super.scanChar(character)) return false;
    _adjustLineAndColumn(character);
    return true;
  }

  @override
  int readChar() {
    final character = super.readChar();
    _adjustLineAndColumn(character);
    return character;
  }

  /// Adjusts [_line] and [_column] after having consumed [character].
  void _adjustLineAndColumn(int character) {
    if (character == $lf || (character == $cr && peekChar() != $lf)) {
      _line += 1;
      _column = 0;
    } else {
      _column += 1;
    }
  }

  @override
  bool scan(Pattern pattern) {
    if (!super.scan(pattern)) return false;
    final firstMatch = (lastMatch![0])!;

    final newlines = _newlinesIn(firstMatch);
    _line += newlines.length;
    if (newlines.isEmpty) {
      _column += firstMatch.length;
    } else {
      _column = firstMatch.length - newlines.last.end;
    }

    return true;
  }

  /// Returns a list of [Match]es describing all the newlines in [text], which
  /// is assumed to end at [position].
  List<Match> _newlinesIn(String text) {
    final newlines = _newlineRegExp.allMatches(text).toList();
    if (_betweenCRLF) newlines.removeLast();
    return newlines;
  }
}

/// A class representing the state of an [EagerSpanScanner].
class _EagerSpanScannerState implements LineScannerState {
  final EagerSpanScanner _scanner;
  @override
  final int position;
  @override
  final int line;
  @override
  final int column;

  _EagerSpanScannerState(this._scanner, this.position, this.line, this.column);
}
