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

/// The location of a character represented as a line and column pair.
class CharacterLocation {
  /// The one-based index of the line containing the character.
  final int lineNumber;

  /// The one-based index of the column containing the character.
  final int columnNumber;

  /// Initialize a newly created location to represent the location of the
  /// character at the given [lineNumber] and [columnNumber].
  CharacterLocation(this.lineNumber, this.columnNumber);

  @override
  bool operator ==(Object object) =>
      object is CharacterLocation &&
      lineNumber == object.lineNumber &&
      columnNumber == object.columnNumber;

  @override
  String toString() => '$lineNumber:$columnNumber';
}

/// Information about line and column information within a source file.
class LineInfo {
  /// A list containing the offsets of the first character of each line in the
  /// source code.
  final List<int> lineStarts;

  /// The zero-based [lineStarts] index resulting from the last call to
  /// [getLocation].
  int _previousLine = 0;

  /// Initialize a newly created set of line information to represent the data
  /// encoded in the given list of [lineStarts].
  LineInfo(this.lineStarts) {
    if (lineStarts.isEmpty) {
      throw ArgumentError("lineStarts must be non-empty");
    }
  }

  /// Initialize a newly created set of line information corresponding to the
  /// given file [content]. Lines end with `\r`, `\n` or `\r\n`.
  factory LineInfo.fromContent(String content) {
    const slashN = 0x0A;
    const slashR = 0x0D;

    var lineStarts = <int>[0];
    var length = content.length;
    for (var i = 0; i < length; i++) {
      var unit = content.codeUnitAt(i);
      // Special-case \r\n.
      if (unit == slashR) {
        // Peek ahead to detect a following \n.
        if (i + 1 < length && content.codeUnitAt(i + 1) == slashN) {
          // Line start will get registered at next index at the \n.
        } else {
          lineStarts.add(i + 1);
        }
      }
      // \n
      if (unit == slashN) {
        lineStarts.add(i + 1);
      }
    }

    return LineInfo(lineStarts);
  }

  /// The number of lines.
  int get lineCount => lineStarts.length;

  /// Return the location information for the character at the given [offset].
  CharacterLocation getLocation(int offset) {
    var min = 0;
    var max = lineStarts.length - 1;

    // Subsequent calls to [getLocation] are often for offsets near each other.
    // To take advantage of that, we cache the index of the line start we found
    // when this was last called. If the current offset is on that line or
    // later, we'll skip those early indices completely when searching.
    if (offset >= lineStarts[_previousLine]) {
      min = _previousLine;

      // Before kicking off a full binary search, do a quick check here to see
      // if the new offset is on that exact line.
      if (min == lineStarts.length - 1 || offset < lineStarts[min + 1]) {
        return CharacterLocation(min + 1, offset - lineStarts[min] + 1);
      }
    }

    // Binary search to find the line containing this offset.
    while (min < max) {
      var midpoint = (max - min + 1) ~/ 2 + min;

      if (lineStarts[midpoint] > offset) {
        max = midpoint - 1;
      } else {
        min = midpoint;
      }
    }

    _previousLine = min;

    return CharacterLocation(min + 1, offset - lineStarts[min] + 1);
  }

  /// Return the offset of the first character on the line with the given
  /// [lineNumber].
  int getOffsetOfLine(int lineNumber) {
    if (lineNumber < 0 || lineNumber >= lineCount) {
      throw ArgumentError(
          'Invalid line number: $lineNumber; must be between 0 and ${lineCount - 1}');
    }
    return lineStarts[lineNumber];
  }

  /// Return the offset of the first character on the line following the line
  /// containing the given [offset].
  int getOffsetOfLineAfter(int offset) {
    return getOffsetOfLine(getLocation(offset).lineNumber);
  }
}
