// Copyright (c) 2014, 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 'span.dart';

// TODO(nweiz): Use SourceLocationMixin once we decide to cut a release with
// breaking changes. See SourceLocationMixin for details.

/// A class that describes a single location within a source file.
///
/// This class should not be extended. Instead, [SourceLocationBase] should be
/// extended instead.
class SourceLocation implements Comparable<SourceLocation> {
  /// URL of the source containing this location.
  ///
  /// This may be null, indicating that the source URL is unknown or
  /// unavailable.
  final Uri sourceUrl;

  /// The 0-based offset of this location in the source.
  final int offset;

  /// The 0-based line of this location in the source.
  final int line;

  /// The 0-based column of this location in the source
  final int column;

  /// Returns a representation of this location in the `source:line:column`
  /// format used by text editors.
  ///
  /// This prints 1-based lines and columns.
  String get toolString {
    final source = sourceUrl == null ? 'unknown source' : sourceUrl;
    return '$source:${line + 1}:${column + 1}';
  }

  /// Creates a new location indicating [offset] within [sourceUrl].
  ///
  /// [line] and [column] default to assuming the source is a single line. This
  /// means that [line] defaults to 0 and [column] defaults to [offset].
  ///
  /// [sourceUrl] may be either a [String], a [Uri], or `null`.
  SourceLocation(this.offset, {sourceUrl, int line, int column})
      : sourceUrl =
            sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl as Uri,
        line = line == null ? 0 : line,
        column = column == null ? offset : column {
    if (offset < 0) {
      throw RangeError('Offset may not be negative, was $offset.');
    } else if (line != null && line < 0) {
      throw RangeError('Line may not be negative, was $line.');
    } else if (column != null && column < 0) {
      throw RangeError('Column may not be negative, was $column.');
    }
  }

  /// Returns the distance in characters between `this` and [other].
  ///
  /// This always returns a non-negative value.
  int distance(SourceLocation other) {
    if (sourceUrl != other.sourceUrl) {
      throw ArgumentError('Source URLs \"$sourceUrl\" and '
          "\"${other.sourceUrl}\" don't match.");
    }
    return (offset - other.offset).abs();
  }

  /// Returns a span that covers only a single point: this location.
  SourceSpan pointSpan() => SourceSpan(this, this, '');

  /// Compares two locations.
  ///
  /// [other] must have the same source URL as `this`.
  @override
  int compareTo(SourceLocation other) {
    if (sourceUrl != other.sourceUrl) {
      throw ArgumentError('Source URLs \"$sourceUrl\" and '
          "\"${other.sourceUrl}\" don't match.");
    }
    return offset - other.offset;
  }

  @override
  bool operator ==(other) =>
      other is SourceLocation &&
      sourceUrl == other.sourceUrl &&
      offset == other.offset;

  @override
  int get hashCode => sourceUrl.hashCode + offset;

  @override
  String toString() => '<$runtimeType: $offset $toolString>';
}

/// A base class for source locations with [offset], [line], and [column] known
/// at construction time.
class SourceLocationBase extends SourceLocation {
  SourceLocationBase(int offset, {sourceUrl, int line, int column})
      : super(offset, sourceUrl: sourceUrl, line: line, column: column);
}
