// 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.

import 'dart:math' as math;

import 'package:charcode/charcode.dart';
import 'package:collection/collection.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;
import 'package:term_glyph/term_glyph.dart' as glyph;

import 'colors.dart' as colors;
import 'location.dart';
import 'span.dart';
import 'span_with_context.dart';
import 'utils.dart';

/// A class for writing a chunk of text with a particular span highlighted.
class Highlighter {
  /// The lines to display, including context around the highlighted spans.
  final List<_Line> _lines;

  /// The color to highlight the primary [_Highlight] within its context, or
  /// `null` if it should not be colored.
  final String _primaryColor;

  /// The color to highlight the secondary [_Highlight]s within their context,
  /// or `null` if they should not be colored.
  final String _secondaryColor;

  /// The number of characters before the bar in the sidebar.
  final int _paddingBeforeSidebar;

  /// The maximum number of multiline spans that cover any part of a single
  /// line in [_lines].
  final int _maxMultilineSpans;

  /// Whether [_lines] includes lines from multiple different files.
  final bool _multipleFiles;

  /// The buffer to which to write the result.
  final _buffer = StringBuffer();

  /// The number of spaces to render for hard tabs that appear in `_span.text`.
  ///
  /// We don't want to render raw tabs, because they'll mess up our character
  /// alignment.
  static const _spacesPerTab = 4;

  /// Creates a [Highlighter] that will return a string highlighting [span]
  /// within the text of its file when [highlight] is called.
  ///
  /// [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 [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 no color
  /// should be used.
  ///
  /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
  Highlighter(SourceSpan span, {color})
      : this._(_collateLines([_Highlight(span, primary: true)]), () {
          if (color == true) return colors.red;
          if (color == false) return null;
          return color as String;
        }(), null);

  /// Creates a [Highlighter] that will return a string highlighting
  /// [primarySpan] as well as all the spans in [secondarySpans] within the text
  /// of their file when [highlight] is called.
  ///
  /// Each span has an associated label that will be written alongside it. For
  /// [primarySpan] this message is [primaryLabel], and for [secondarySpans] the
  /// labels are the map values.
  ///
  /// If [color] is `true`, this will use [ANSI terminal color escapes][] to
  /// highlight the text. The [primarySpan] will be highlighted with
  /// [primaryColor] (which defaults to red), and the [secondarySpans] will be
  /// highlighted with [secondaryColor] (which defaults to blue). These
  /// arguments are ignored if [color] is `false`.
  ///
  /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
  Highlighter.multiple(SourceSpan primarySpan, String primaryLabel,
      Map<SourceSpan, String> secondarySpans,
      {bool color = false, String primaryColor, String secondaryColor})
      : this._(
            _collateLines([
              _Highlight(primarySpan, label: primaryLabel, primary: true),
              for (var entry in secondarySpans.entries)
                _Highlight(entry.key, label: entry.value)
            ]),
            color ? (primaryColor ?? colors.red) : null,
            color ? (secondaryColor ?? colors.blue) : null);

  Highlighter._(this._lines, this._primaryColor, this._secondaryColor)
      : _paddingBeforeSidebar = 1 +
            math.max<int>(
                // In a purely mathematical world, floor(log10(n)) would give the
                // number of digits in n, but floating point errors render that
                // unreliable in practice.
                (_lines.last.number + 1).toString().length,
                // If [_lines] aren't contiguous, we'll write "..." in place of a
                // line number.
                _contiguous(_lines) ? 0 : 3),
        _maxMultilineSpans = _lines
            .map((line) => line.highlights
                .where((highlight) => isMultiline(highlight.span))
                .length)
            .reduce(math.max),
        _multipleFiles = !isAllTheSame(_lines.map((line) => line.url));

  /// Returns whether [lines] contains any adjacent lines from the same source
  /// file that aren't adjacent in the original file.
  static bool _contiguous(List<_Line> lines) {
    for (var i = 0; i < lines.length - 1; i++) {
      final thisLine = lines[i];
      final nextLine = lines[i + 1];
      if (thisLine.number + 1 != nextLine.number &&
          thisLine.url == nextLine.url) {
        return false;
      }
    }
    return true;
  }

  /// Collect all the source lines from the contexts of all spans in
  /// [highlights], and associates them with the highlights that cover them.
  static List<_Line> _collateLines(List<_Highlight> highlights) {
    final highlightsByUrl =
        groupBy(highlights, (highlight) => highlight.span.sourceUrl);
    for (var list in highlightsByUrl.values) {
      list.sort((highlight1, highlight2) =>
          highlight1.span.compareTo(highlight2.span));
    }

    return highlightsByUrl.values.expand((highlightsForFile) {
      // First, create a list of all the lines in the current file that we have
      // context for along with their line numbers.
      final lines = <_Line>[];
      for (var highlight in highlightsForFile) {
        final context = highlight.span.context;
        // If [highlight.span.context] contains lines prior to the one
        // [highlight.span.text] appears on, write those first.
        final lineStart = findLineStart(
            context, highlight.span.text, highlight.span.start.column);
        assert(lineStart != null); // enforced by [_normalizeContext]

        final linesBeforeSpan =
            '\n'.allMatches(context.substring(0, lineStart)).length;

        final url = highlight.span.sourceUrl;
        var lineNumber = highlight.span.start.line - linesBeforeSpan;
        for (var line in context.split('\n')) {
          // Only add a line if it hasn't already been added for a previous span.
          if (lines.isEmpty || lineNumber > lines.last.number) {
            lines.add(_Line(line, lineNumber, url));
          }
          lineNumber++;
        }
      }

      // Next, associate each line with each highlights that covers it.
      final activeHighlights = <_Highlight>[];
      var highlightIndex = 0;
      for (var line in lines) {
        activeHighlights.removeWhere((highlight) =>
            highlight.span.sourceUrl != line.url ||
            highlight.span.end.line < line.number);

        final oldHighlightLength = activeHighlights.length;
        for (var highlight in highlightsForFile.skip(highlightIndex)) {
          if (highlight.span.start.line > line.number) break;
          if (highlight.span.sourceUrl != line.url) break;
          activeHighlights.add(highlight);
        }
        highlightIndex += activeHighlights.length - oldHighlightLength;

        line.highlights.addAll(activeHighlights);
      }

      return lines;
    }).toList();
  }

  /// Returns the highlighted span text.
  ///
  /// This method should only be called once.
  String highlight() {
    _writeFileStart(_lines.first.url);

    // Each index of this list represents a column after the sidebar that could
    // contain a line indicating an active highlight. If it's `null`, that
    // column is empty; if it contains a highlight, it should be drawn for that column.
    final highlightsByColumn = List<_Highlight>(_maxMultilineSpans);

    for (var i = 0; i < _lines.length; i++) {
      final line = _lines[i];
      if (i > 0) {
        final lastLine = _lines[i - 1];
        if (lastLine.url != line.url) {
          _writeSidebar(end: glyph.upEnd);
          _buffer.writeln();
          _writeFileStart(line.url);
        } else if (lastLine.number + 1 != line.number) {
          _writeSidebar(text: '...');
          _buffer.writeln();
        }
      }

      // If a highlight covers the entire first line other than initial
      // whitespace, don't bother pointing out exactly where it begins. Iterate
      // in reverse so that longer highlights (which are sorted after shorter
      // highlights) appear further out, leading to fewer crossed lines.
      for (var highlight in line.highlights.reversed) {
        if (isMultiline(highlight.span) &&
            highlight.span.start.line == line.number &&
            _isOnlyWhitespace(
                line.text.substring(0, highlight.span.start.column))) {
          replaceFirstNull(highlightsByColumn, highlight);
        }
      }

      _writeSidebar(line: line.number);
      _buffer.write(' ');
      _writeMultilineHighlights(line, highlightsByColumn);
      if (highlightsByColumn.isNotEmpty) _buffer.write(' ');

      final primary = line.highlights
          .firstWhere((highlight) => highlight.isPrimary, orElse: () => null);
      if (primary != null) {
        _writeHighlightedText(
            line.text,
            primary.span.start.line == line.number
                ? primary.span.start.column
                : 0,
            primary.span.end.line == line.number
                ? primary.span.end.column
                : line.text.length,
            color: _primaryColor);
      } else {
        _writeText(line.text);
      }
      _buffer.writeln();

      // Always write the primary span's indicator first so that it's right next
      // to the highlighted text.
      if (primary != null) _writeIndicator(line, primary, highlightsByColumn);
      for (var highlight in line.highlights) {
        if (highlight.isPrimary) continue;
        _writeIndicator(line, highlight, highlightsByColumn);
      }
    }

    _writeSidebar(end: glyph.upEnd);
    return _buffer.toString();
  }

  /// Writes the beginning of the file highlight for the file with the given
  /// [url].
  void _writeFileStart(Uri url) {
    if (!_multipleFiles || url == null) {
      _writeSidebar(end: glyph.downEnd);
    } else {
      _writeSidebar(end: glyph.topLeftCorner);
      _colorize(() => _buffer.write('${glyph.horizontalLine * 2}>'),
          color: colors.blue);
      _buffer.write(' ${p.prettyUri(url)}');
    }
    _buffer.writeln();
  }

  /// Writes the post-sidebar highlight bars for [line] according to
  /// [highlightsByColumn].
  ///
  /// If [current] is passed, it's the highlight for which an indicator is being
  /// written. If it appears in [highlightsByColumn], a horizontal line is
  /// written from its column to the rightmost column.
  void _writeMultilineHighlights(
      _Line line, List<_Highlight> highlightsByColumn,
      {_Highlight current}) {
    // Whether we've written a sidebar indicator for opening a new span on this
    // line, and which color should be used for that indicator's rightward line.
    var openedOnThisLine = false;
    String openedOnThisLineColor;

    final currentColor = current == null
        ? null
        : current.isPrimary ? _primaryColor : _secondaryColor;
    var foundCurrent = false;
    for (var highlight in highlightsByColumn) {
      final startLine = highlight?.span?.start?.line;
      final endLine = highlight?.span?.end?.line;
      if (current != null && highlight == current) {
        foundCurrent = true;
        assert(startLine == line.number || endLine == line.number);
        _colorize(() {
          _buffer.write(startLine == line.number
              ? glyph.topLeftCorner
              : glyph.bottomLeftCorner);
        }, color: currentColor);
      } else if (foundCurrent) {
        _colorize(() {
          _buffer.write(highlight == null ? glyph.horizontalLine : glyph.cross);
        }, color: currentColor);
      } else if (highlight == null) {
        if (openedOnThisLine) {
          _colorize(() => _buffer.write(glyph.horizontalLine),
              color: openedOnThisLineColor);
        } else {
          _buffer.write(' ');
        }
      } else {
        _colorize(() {
          final vertical = openedOnThisLine ? glyph.cross : glyph.verticalLine;
          if (current != null) {
            _buffer.write(vertical);
          } else if (startLine == line.number) {
            _colorize(() {
              _buffer
                  .write(glyph.glyphOrAscii(openedOnThisLine ? '┬' : '┌', '/'));
            }, color: openedOnThisLineColor);
            openedOnThisLine = true;
            openedOnThisLineColor ??=
                highlight.isPrimary ? _primaryColor : _secondaryColor;
          } else if (endLine == line.number &&
              highlight.span.end.column == line.text.length) {
            _buffer.write(highlight.label == null
                ? glyph.glyphOrAscii('└', '\\')
                : vertical);
          } else {
            _colorize(() {
              _buffer.write(vertical);
            }, color: openedOnThisLineColor);
          }
        }, color: highlight.isPrimary ? _primaryColor : _secondaryColor);
      }
    }
  }

  // Writes [text], with text between [startColumn] and [endColumn] colorized in
  // the same way as [_colorize].
  void _writeHighlightedText(String text, int startColumn, int endColumn,
      {@required String color}) {
    _writeText(text.substring(0, startColumn));
    _colorize(() => _writeText(text.substring(startColumn, endColumn)),
        color: color);
    _writeText(text.substring(endColumn, text.length));
  }

  /// Writes an indicator for where [highlight] starts, ends, or both below
  /// [line].
  ///
  /// This may either add or remove [highlight] from [highlightsByColumn].
  void _writeIndicator(
      _Line line, _Highlight highlight, List<_Highlight> highlightsByColumn) {
    final color = highlight.isPrimary ? _primaryColor : _secondaryColor;
    if (!isMultiline(highlight.span)) {
      _writeSidebar();
      _buffer.write(' ');
      _writeMultilineHighlights(line, highlightsByColumn, current: highlight);
      if (highlightsByColumn.isNotEmpty) _buffer.write(' ');

      _colorize(() {
        _writeUnderline(line, highlight.span,
            highlight.isPrimary ? '^' : glyph.horizontalLineBold);
        _writeLabel(highlight.label);
      }, color: color);
      _buffer.writeln();
    } else if (highlight.span.start.line == line.number) {
      if (highlightsByColumn.contains(highlight)) return;
      replaceFirstNull(highlightsByColumn, highlight);

      _writeSidebar();
      _buffer.write(' ');
      _writeMultilineHighlights(line, highlightsByColumn, current: highlight);
      _colorize(() => _writeArrow(line, highlight.span.start.column),
          color: color);
      _buffer.writeln();
    } else if (highlight.span.end.line == line.number) {
      final coversWholeLine = highlight.span.end.column == line.text.length;
      if (coversWholeLine && highlight.label == null) {
        replaceWithNull(highlightsByColumn, highlight);
        return;
      }

      _writeSidebar();
      _buffer.write(' ');
      _writeMultilineHighlights(line, highlightsByColumn, current: highlight);

      _colorize(() {
        if (coversWholeLine) {
          _buffer.write(glyph.horizontalLine * 3);
        } else {
          _writeArrow(line, math.max(highlight.span.end.column - 1, 0),
              beginning: false);
        }
        _writeLabel(highlight.label);
      }, color: color);
      _buffer.writeln();
      replaceWithNull(highlightsByColumn, highlight);
    }
  }

  /// Underlines the portion of [line] covered by [span] with repeated instances
  /// of [character].
  void _writeUnderline(_Line line, SourceSpan span, String character) {
    assert(!isMultiline(span));
    assert(line.text.contains(span.text));

    var startColumn = span.start.column;
    var endColumn = span.end.column;

    // Adjust the start and end columns to account for any tabs that were
    // converted to spaces.
    final tabsBefore = _countTabs(line.text.substring(0, startColumn));
    final tabsInside = _countTabs(line.text.substring(startColumn, endColumn));
    startColumn += tabsBefore * (_spacesPerTab - 1);
    endColumn += (tabsBefore + tabsInside) * (_spacesPerTab - 1);

    _buffer
      ..write(' ' * startColumn)
      ..write(character * math.max(endColumn - startColumn, 1));
  }

  /// Write an arrow pointing to column [column] in [line].
  ///
  /// If the arrow points to a tab character, this will point to the beginning
  /// of the tab if [beginning] is `true` and the end if it's `false`.
  void _writeArrow(_Line line, int column, {bool beginning = true}) {
    final tabs =
        _countTabs(line.text.substring(0, column + (beginning ? 0 : 1)));
    _buffer
      ..write(glyph.horizontalLine * (1 + column + tabs * (_spacesPerTab - 1)))
      ..write('^');
  }

  /// Writes a space followed by [label] if [label] isn't `null`.
  void _writeLabel(String label) {
    if (label != null) _buffer.write(' $label');
  }

  /// Writes a snippet from the source text, converting hard tab characters into
  /// plain indentation.
  void _writeText(String text) {
    for (var char in text.codeUnits) {
      if (char == $tab) {
        _buffer.write(' ' * _spacesPerTab);
      } else {
        _buffer.writeCharCode(char);
      }
    }
  }

  // Writes a sidebar to [buffer] that includes [line] as the line number if
  // given and writes [end] at the end (defaults to [glyphs.verticalLine]).
  //
  // If [text] is given, it's used in place of the line number. It can't be
  // passed at the same time as [line].
  void _writeSidebar({int line, String text, String end}) {
    assert(line == null || text == null);

    // Add 1 to line to convert from computer-friendly 0-indexed line numbers to
    // human-friendly 1-indexed line numbers.
    if (line != null) text = (line + 1).toString();
    _colorize(() {
      _buffer
        ..write((text ?? '').padRight(_paddingBeforeSidebar))
        ..write(end ?? glyph.verticalLine);
    }, color: colors.blue);
  }

  /// Returns the number of hard tabs in [text].
  int _countTabs(String text) {
    var count = 0;
    for (var char in text.codeUnits) {
      if (char == $tab) count++;
    }
    return count;
  }

  /// Returns whether [text] contains only space or tab characters.
  bool _isOnlyWhitespace(String text) {
    for (var char in text.codeUnits) {
      if (char != $space && char != $tab) return false;
    }
    return true;
  }

  /// Colors all text written to [_buffer] during [callback], if colorization is
  /// enabled and [color] is not `null`.
  void _colorize(void Function() callback, {@required String color}) {
    if (_primaryColor != null && color != null) _buffer.write(color);
    callback();
    if (_primaryColor != null && color != null) _buffer.write(colors.none);
  }
}

/// Information about how to highlight a single section of a source file.
class _Highlight {
  /// The section of the source file to highlight.
  ///
  /// This is normalized to make it easier for [Highlighter] to work with.
  final SourceSpanWithContext span;

  /// Whether this is the primary span in the highlight.
  ///
  /// The primary span is highlighted with a different character and colored
  /// differently than non-primary spans.
  final bool isPrimary;

  /// The label to include inline when highlighting [span].
  ///
  /// This helps distinguish clarify what each highlight means when multiple are
  /// used in the same message.
  final String label;

  _Highlight(SourceSpan span, {this.label, bool primary = false})
      : span = (() {
          var newSpan = _normalizeContext(span);
          newSpan = _normalizeNewlines(newSpan);
          newSpan = _normalizeTrailingNewline(newSpan);
          return _normalizeEndOfLine(newSpan);
        })(),
        isPrimary = primary;

  /// Normalizes [span] to ensure that it's a [SourceSpanWithContext] whose
  /// context actually contains its text at the expected column.
  ///
  /// If it's not already a [SourceSpanWithContext], adjust the start and end
  /// locations' line and column fields so that the highlighter can assume they
  /// match up with the context.
  static SourceSpanWithContext _normalizeContext(SourceSpan span) =>
      span is SourceSpanWithContext &&
              findLineStart(span.context, span.text, span.start.column) != null
          ? span
          : SourceSpanWithContext(
              SourceLocation(span.start.offset,
                  sourceUrl: span.sourceUrl, line: 0, column: 0),
              SourceLocation(span.end.offset,
                  sourceUrl: span.sourceUrl,
                  line: countCodeUnits(span.text, $lf),
                  column: _lastLineLength(span.text)),
              span.text,
              span.text);

  /// Normalizes [span] to replace Windows-style newlines with Unix-style
  /// newlines.
  static SourceSpanWithContext _normalizeNewlines(SourceSpanWithContext span) {
    final text = span.text;
    if (!text.contains('\r\n')) return span;

    var endOffset = span.end.offset;
    for (var i = 0; i < text.length - 1; i++) {
      if (text.codeUnitAt(i) == $cr && text.codeUnitAt(i + 1) == $lf) {
        endOffset--;
      }
    }

    return SourceSpanWithContext(
        span.start,
        SourceLocation(endOffset,
            sourceUrl: span.sourceUrl,
            line: span.end.line,
            column: span.end.column),
        text.replaceAll('\r\n', '\n'),
        span.context.replaceAll('\r\n', '\n'));
  }

  /// Normalizes [span] to remove a trailing newline from `span.context`.
  ///
  /// If necessary, also adjust `span.end` so that it doesn't point past where
  /// the trailing newline used to be.
  static SourceSpanWithContext _normalizeTrailingNewline(
      SourceSpanWithContext span) {
    if (!span.context.endsWith('\n')) return span;

    // If there's a full blank line on the end of [span.context], it's probably
    // significant, so we shouldn't trim it.
    if (span.text.endsWith('\n\n')) return span;

    final context = span.context.substring(0, span.context.length - 1);
    var text = span.text;
    var start = span.start;
    var end = span.end;
    if (span.text.endsWith('\n') && _isTextAtEndOfContext(span)) {
      text = span.text.substring(0, span.text.length - 1);
      if (text.isEmpty) {
        end = start;
      } else {
        end = SourceLocation(span.end.offset - 1,
            sourceUrl: span.sourceUrl,
            line: span.end.line - 1,
            column: _lastLineLength(context));
        start = span.start.offset == span.end.offset ? end : span.start;
      }
    }
    return SourceSpanWithContext(start, end, text, context);
  }

  /// Normalizes [span] so that the end location is at the end of a line rather
  /// than at the beginning of the next line.
  static SourceSpanWithContext _normalizeEndOfLine(SourceSpanWithContext span) {
    if (span.end.column != 0) return span;
    if (span.end.line == span.start.line) return span;

    final text = span.text.substring(0, span.text.length - 1);

    return SourceSpanWithContext(
        span.start,
        SourceLocation(span.end.offset - 1,
            sourceUrl: span.sourceUrl,
            line: span.end.line - 1,
            column: text.length - text.lastIndexOf('\n') - 1),
        text,
        // If the context also ends with a newline, it's possible that we don't
        // have the full context for that line, so we shouldn't print it at all.
        span.context.endsWith('\n')
            ? span.context.substring(0, span.context.length - 1)
            : span.context);
  }

  /// Returns the length of the last line in [text], whether or not it ends in a
  /// newline.
  static int _lastLineLength(String text) {
    if (text.isEmpty) {
      return 0;
    } else if (text.codeUnitAt(text.length - 1) == $lf) {
      return text.length == 1
          ? 0
          : text.length - text.lastIndexOf('\n', text.length - 2) - 1;
    } else {
      return text.length - text.lastIndexOf('\n') - 1;
    }
  }

  /// Returns whether [span]'s text runs all the way to the end of its context.
  static bool _isTextAtEndOfContext(SourceSpanWithContext span) =>
      findLineStart(span.context, span.text, span.start.column) +
          span.start.column +
          span.length ==
      span.context.length;

  @override
  String toString() {
    final buffer = StringBuffer();
    if (isPrimary) buffer.write('primary ');
    buffer.write('${span.start.line}:${span.start.column}-'
        '${span.end.line}:${span.end.column}');
    if (label != null) buffer.write(' ($label)');
    return buffer.toString();
  }
}

/// A single line of the source file being highlighted.
class _Line {
  /// The text of the line, not including the trailing newline.
  final String text;

  /// The 0-based line number in the source file.
  final int number;

  /// The URL of the source file in which this line appears.
  final Uri url;

  /// All highlights that cover any portion of this line, in source span order.
  ///
  /// This is populated after the initial line is created.
  final highlights = <_Highlight>[];

  _Line(this.text, this.number, this.url);

  @override
  String toString() => '$number: "$text" (${highlights.join(', ')})';
}
