// 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 'highlighter.dart';
import 'span.dart';
import 'span_with_context.dart';
import 'utils.dart';

/// A mixin for easily implementing [SourceSpan].
///
/// This implements the [SourceSpan] methods in terms of [start], [end], and
/// [text]. This assumes that [start] and [end] have the same source URL, that
/// [start] comes before [end], and that [text] has a number of characters equal
/// to the distance between [start] and [end].
abstract class SourceSpanMixin implements SourceSpan {
  @override
  Uri? get sourceUrl => start.sourceUrl;

  @override
  int get length => end.offset - start.offset;

  @override
  int compareTo(SourceSpan other) {
    final result = start.compareTo(other.start);
    return result == 0 ? end.compareTo(other.end) : result;
  }

  @override
  SourceSpan union(SourceSpan other) {
    if (sourceUrl != other.sourceUrl) {
      throw ArgumentError('Source URLs \"$sourceUrl\" and '
          " \"${other.sourceUrl}\" don't match.");
    }

    final start = min(this.start, other.start);
    final end = max(this.end, other.end);
    final beginSpan = start == this.start ? this : other;
    final endSpan = end == this.end ? this : other;

    if (beginSpan.end.compareTo(endSpan.start) < 0) {
      throw ArgumentError('Spans $this and $other are disjoint.');
    }

    final text = beginSpan.text +
        endSpan.text.substring(beginSpan.end.distance(endSpan.start));
    return SourceSpan(start, end, text);
  }

  @override
  String message(String message, {color}) {
    final buffer = StringBuffer()
      ..write('line ${start.line + 1}, column ${start.column + 1}');
    if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}');
    buffer.write(': $message');

    final highlight = this.highlight(color: color);
    if (highlight.isNotEmpty) {
      buffer
        ..writeln()
        ..write(highlight);
    }

    return buffer.toString();
  }

  @override
  String highlight({color}) {
    if (this is! SourceSpanWithContext && length == 0) return '';
    return Highlighter(this, color: color).highlight();
  }

  @override
  bool operator ==(other) =>
      other is SourceSpan && start == other.start && end == other.end;

  @override
  int get hashCode => start.hashCode + (31 * end.hashCode);

  @override
  String toString() => '<$runtimeType: from $start to $end "$text">';
}
