// 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 'package:path/path.dart' as p;
import 'package:term_glyph/term_glyph.dart' as glyph;

import 'charcode.dart';
import 'file.dart';
import 'highlighter.dart';
import 'location.dart';
import 'span_mixin.dart';
import 'span_with_context.dart';

/// A class that describes a segment of source text.
abstract class SourceSpan implements Comparable<SourceSpan> {
  /// The start location of this span.
  SourceLocation get start;

  /// The end location of this span, exclusive.
  SourceLocation get end;

  /// The source text for this span.
  String get text;

  /// The URL of the source (typically a file) of this span.
  ///
  /// This may be null, indicating that the source URL is unknown or
  /// unavailable.
  Uri? get sourceUrl;

  /// The length of this span, in characters.
  int get length;

  /// Creates a new span from [start] to [end] (exclusive) containing [text].
  ///
  /// [start] and [end] must have the same source URL and [start] must come
  /// before [end]. [text] must have a number of characters equal to the
  /// distance between [start] and [end].
  factory SourceSpan(SourceLocation start, SourceLocation end, String text) =>
      SourceSpanBase(start, end, text);

  /// Creates a new span that's the union of `this` and [other].
  ///
  /// The two spans must have the same source URL and may not be disjoint.
  /// [text] is computed by combining `this.text` and `other.text`.
  SourceSpan union(SourceSpan other);

  /// Compares two spans.
  ///
  /// [other] must have the same source URL as `this`. This orders spans by
  /// [start] then [length].
  @override
  int compareTo(SourceSpan other);

  /// Formats [message] in a human-friendly way associated with this span.
  ///
  /// [color] may either be a [String], a [bool], or `null`. If it's a string,
  /// it indicates an [ANSI terminal color escape][] that should
  /// be used to highlight the span's text (for example, `"\u001b[31m"` will
  /// color red). If it's `true`, it indicates that the text should be
  /// highlighted using the default color. If it's `false` or `null`, it
  /// indicates that the text shouldn't be highlighted.
  ///
  /// This uses the full range of Unicode characters to highlight the source
  /// span if [glyph.ascii] is `false` (the default), but only uses ASCII
  /// characters if it's `true`.
  ///
  /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
  String message(String message, {color});

  /// Prints the text associated with this span in a user-friendly way.
  ///
  /// This is identical to [message], except that it doesn't print the file
  /// name, line number, column number, or message. If [length] is 0 and this
  /// isn't a [SourceSpanWithContext], returns an empty string.
  ///
  /// [color] may either be a [String], a [bool], or `null`. If it's a string,
  /// it indicates an [ANSI terminal color escape][] that should
  /// be used to highlight the span's text (for example, `"\u001b[31m"` will
  /// color red). If it's `true`, it indicates that the text should be
  /// highlighted using the default color. If it's `false` or `null`, it
  /// indicates that the text shouldn't be highlighted.
  ///
  /// This uses the full range of Unicode characters to highlight the source
  /// span if [glyph.ascii] is `false` (the default), but only uses ASCII
  /// characters if it's `true`.
  ///
  /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
  String highlight({color});
}

/// A base class for source spans with [start], [end], and [text] known at
/// construction time.
class SourceSpanBase extends SourceSpanMixin {
  @override
  final SourceLocation start;
  @override
  final SourceLocation end;
  @override
  final String text;

  SourceSpanBase(this.start, this.end, this.text) {
    if (end.sourceUrl != start.sourceUrl) {
      throw ArgumentError('Source URLs \"${start.sourceUrl}\" and '
          " \"${end.sourceUrl}\" don't match.");
    } else if (end.offset < start.offset) {
      throw ArgumentError('End $end must come after start $start.');
    } else if (text.length != start.distance(end)) {
      throw ArgumentError('Text "$text" must be ${start.distance(end)} '
          'characters long.');
    }
  }
}

// TODO(#52): Move these to instance methods in the next breaking release.
/// Extension methods on the base [SourceSpan] API.
extension SourceSpanExtension on SourceSpan {
  /// Like [SourceSpan.message], but also highlights [secondarySpans] to provide
  /// the user with additional context.
  ///
  /// Each span takes a label ([label] for this span, and the values of the
  /// [secondarySpans] map for the secondary spans) that's used to indicate to
  /// the user what that particular span represents.
  ///
  /// If [color] is `true`, [ANSI terminal color escapes][] are used to color
  /// the resulting string. By default this span is colored red and the
  /// secondary spans are colored blue, but that can be customized by passing
  /// ANSI escape strings to [primaryColor] or [secondaryColor].
  ///
  /// [ANSI terminal color escapes]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
  ///
  /// Each span in [secondarySpans] must refer to the same document as this
  /// span. Throws an [ArgumentError] if any secondary span has a different
  /// source URL than this span.
  ///
  /// Note that while this will work with plain [SourceSpan]s, it will produce
  /// much more useful output with [SourceSpanWithContext]s (including
  /// [FileSpan]s).
  String messageMultiple(
      String message, String label, Map<SourceSpan, String> secondarySpans,
      {bool color = false, String? primaryColor, String? secondaryColor}) {
    final buffer = StringBuffer()
      ..write('line ${start.line + 1}, column ${start.column + 1}');
    if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}');
    buffer
      ..writeln(': $message')
      ..write(highlightMultiple(label, secondarySpans,
          color: color,
          primaryColor: primaryColor,
          secondaryColor: secondaryColor));
    return buffer.toString();
  }

  /// Like [SourceSpan.highlight], but also highlights [secondarySpans] to
  /// provide the user with additional context.
  ///
  /// Each span takes a label ([label] for this span, and the values of the
  /// [secondarySpans] map for the secondary spans) that's used to indicate to
  /// the user what that particular span represents.
  ///
  /// If [color] is `true`, [ANSI terminal color escapes][] are used to color
  /// the resulting string. By default this span is colored red and the
  /// secondary spans are colored blue, but that can be customized by passing
  /// ANSI escape strings to [primaryColor] or [secondaryColor].
  ///
  /// [ANSI terminal color escapes]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
  ///
  /// Each span in [secondarySpans] must refer to the same document as this
  /// span. Throws an [ArgumentError] if any secondary span has a different
  /// source URL than this span.
  ///
  /// Note that while this will work with plain [SourceSpan]s, it will produce
  /// much more useful output with [SourceSpanWithContext]s (including
  /// [FileSpan]s).
  String highlightMultiple(String label, Map<SourceSpan, String> secondarySpans,
          {bool color = false, String? primaryColor, String? secondaryColor}) =>
      Highlighter.multiple(this, label, secondarySpans,
              color: color,
              primaryColor: primaryColor,
              secondaryColor: secondaryColor)
          .highlight();

  /// Returns a span from [start] code units (inclusive) to [end] code units
  /// (exclusive) after the beginning of this span.
  SourceSpan subspan(int start, [int? end]) {
    RangeError.checkValidRange(start, end, length);
    if (start == 0 && (end == null || end == length)) return this;

    final text = this.text;
    final startLocation = this.start;
    var line = startLocation.line;
    var column = startLocation.column;

    // Adjust [line] and [column] as necessary if the character at [i] in [text]
    // is a newline.
    void consumeCodePoint(int i) {
      final codeUnit = text.codeUnitAt(i);
      if (codeUnit == $lf ||
          // A carriage return counts as a newline, but only if it's not
          // followed by a line feed.
          (codeUnit == $cr &&
              (i + 1 == text.length || text.codeUnitAt(i + 1) != $lf))) {
        line += 1;
        column = 0;
      } else {
        column += 1;
      }
    }

    for (var i = 0; i < start; i++) {
      consumeCodePoint(i);
    }

    final newStartLocation = SourceLocation(startLocation.offset + start,
        sourceUrl: sourceUrl, line: line, column: column);

    SourceLocation newEndLocation;
    if (end == null || end == length) {
      newEndLocation = this.end;
    } else if (end == start) {
      newEndLocation = newStartLocation;
    } else {
      for (var i = start; i < end; i++) {
        consumeCodePoint(i);
      }
      newEndLocation = SourceLocation(startLocation.offset + end,
          sourceUrl: sourceUrl, line: line, column: column);
    }

    return SourceSpan(
        newStartLocation, newEndLocation, text.substring(start, end));
  }
}
