// 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: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 span to highlight.
  final SourceSpanWithContext _span;

  /// The color to highlight [_span] within its context, or `null` if the span
  /// should not be colored.
  final String _color;

  /// Whether [_span] covers multiple lines.
  final bool _multiline;

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

  // The number of characters between the bar in the sidebar and the text
  // being highlighted.
  int get _paddingAfterSidebar =>
      // This is just a space for a single-line span, but for a multi-line span
      // needs to accommodate " | ".
      _multiline ? 3 : 1;

  /// 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 message associated with [span]
  /// 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 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.
  ///
  /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
  factory Highlighter(SourceSpan span, {color}) {
    if (color == true) color = colors.red;
    if (color == false) color = null;

    var newSpan = _normalizeContext(span);
    newSpan = _normalizeNewlines(newSpan);
    newSpan = _normalizeTrailingNewline(newSpan);
    newSpan = _normalizeEndOfLine(newSpan);

    return Highlighter._(newSpan, color as String);
  }

  /// 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);
      end = SourceLocation(span.end.offset - 1,
          sourceUrl: span.sourceUrl,
          line: span.end.line - 1,
          column: _lastLineLength(text));
      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: _lastLineLength(text)),
        text,
        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;

    // The "- 1" here avoids counting the newline itself.
    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;

  Highlighter._(this._span, this._color)
      : _multiline = _span.start.line != _span.end.line,
        // 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.
        _paddingBeforeSidebar = (_span.end.line + 1).toString().length + 1;

  /// Returns the highlighted span text.
  ///
  /// This method should only be called once.
  String highlight() {
    _writeSidebar(end: glyph.downEnd);
    _buffer.writeln();

    // If [_span.context] contains lines prior to the one [_span.text] appears
    // on, write those first.
    final lineStart =
        findLineStart(_span.context, _span.text, _span.start.column);
    assert(lineStart != null); // enforced by [_normalizeContext]

    var context = _span.context;
    if (lineStart > 0) {
      // Take a substring to one character *before* [lineStart] because
      // [findLineStart] is guaranteed to return a position immediately after a
      // newline. Including that newline would add an extra empty line to the
      // end of [lines].
      final lines = context.substring(0, lineStart - 1).split('\n');
      var lineNumber = _span.start.line - lines.length;
      for (var line in lines) {
        _writeSidebar(line: lineNumber);
        _buffer.write(' ' * _paddingAfterSidebar);
        _writeText(line);
        _buffer.writeln();
        lineNumber++;
      }
      context = context.substring(lineStart);
    }

    final lines = context.split('\n');

    final lastLineIndex = _span.end.line - _span.start.line;
    if (lines.last.isEmpty && lines.length > lastLineIndex + 1) {
      // Trim a trailing newline so we don't add an empty line to the end of the
      // highlight.
      lines.removeLast();
    }

    _writeFirstLine(lines.first);
    if (_multiline) {
      _writeIntermediateLines(lines.skip(1).take(lastLineIndex - 1));
      _writeLastLine(lines[lastLineIndex]);
    }
    _writeTrailingLines(lines.skip(lastLineIndex + 1));

    _writeSidebar(end: glyph.upEnd);

    return _buffer.toString();
  }

  // Writes the first (and possibly only) line highlighted by the span.
  void _writeFirstLine(String line) {
    _writeSidebar(line: _span.start.line);

    var startColumn = math.min(_span.start.column, line.length);
    var endColumn = math.min(
        startColumn + _span.end.offset - _span.start.offset, line.length);
    final textBefore = line.substring(0, startColumn);

    // If the span covers the entire first line other than initial whitespace,
    // don't bother pointing out exactly where it begins.
    if (_multiline && _isOnlyWhitespace(textBefore)) {
      _buffer.write(' ');
      _colorize(() {
        _buffer..write(glyph.glyphOrAscii('┌', '/'))..write(' ');
        _writeText(line);
      });
      _buffer.writeln();
      return;
    }

    _buffer.write(' ' * _paddingAfterSidebar);
    _writeText(textBefore);
    final textInside = line.substring(startColumn, endColumn);
    _colorize(() => _writeText(textInside));
    _writeText(line.substring(endColumn));
    _buffer.writeln();

    // Adjust the start and end column to account for any tabs that were
    // converted to spaces.
    final tabsBefore = _countTabs(textBefore);
    final tabsInside = _countTabs(textInside);
    startColumn = startColumn + tabsBefore * (_spacesPerTab - 1);
    endColumn = endColumn + (tabsBefore + tabsInside) * (_spacesPerTab - 1);

    // Write the highlight for the first line. This is a series of carets for a
    // single-line span, and a pointer to the beginning of a multi-line span.
    _writeSidebar();
    if (_multiline) {
      _buffer.write(' ');
      _colorize(() {
        _buffer
          ..write(glyph.topLeftCorner)
          ..write(glyph.horizontalLine * (startColumn + 1))
          ..write('^');
      });
    } else {
      _buffer.write(' ' * (startColumn + 1));
      _colorize(
          () => _buffer.write('^' * math.max(endColumn - startColumn, 1)));
    }
    _buffer.writeln();
  }

  /// Writes the lines between the first and last lines highlighted by the span.
  void _writeIntermediateLines(Iterable<String> lines) {
    assert(_multiline);

    // +1 because the first line was already written.
    var lineNumber = _span.start.line + 1;
    for (var line in lines) {
      _writeSidebar(line: lineNumber);

      _buffer.write(' ');
      _colorize(() {
        _buffer..write(glyph.verticalLine)..write(' ');
        _writeText(line);
      });
      _buffer.writeln();

      lineNumber++;
    }
  }

  // Writes the last line highlighted by the span.
  void _writeLastLine(String line) {
    assert(_multiline);

    _writeSidebar(line: _span.end.line);

    var endColumn = math.min(_span.end.column, line.length);

    // If the span covers the entire last line, don't bother pointing out
    // exactly where it ends.
    if (_multiline && endColumn == line.length) {
      _buffer.write(' ');
      _colorize(() {
        _buffer..write(glyph.glyphOrAscii('└', '\\'))..write(' ');
        _writeText(line);
      });
      _buffer.writeln();
      return;
    }

    _buffer.write(' ');
    final textInside = line.substring(0, endColumn);
    _colorize(() {
      _buffer..write(glyph.verticalLine)..write(' ');
      _writeText(textInside);
    });
    _writeText(line.substring(endColumn));
    _buffer.writeln();

    // Adjust the end column to account for any tabs that were converted to
    // spaces.
    final tabsInside = _countTabs(textInside);
    endColumn = endColumn + tabsInside * (_spacesPerTab - 1);

    // Write the highlight for the final line, which is an arrow pointing to the
    // end of the span.
    _writeSidebar();
    _buffer.write(' ');
    _colorize(() {
      _buffer
        ..write(glyph.bottomLeftCorner)
        ..write(glyph.horizontalLine * endColumn)
        ..write('^');
    });
    _buffer.writeln();
  }

  /// Writes lines that appear in the context string but come after the span.
  void _writeTrailingLines(Iterable<String> lines) {
    // +1 because this comes after any lines covered by the span.
    var lineNumber = _span.end.line + 1;
    for (var line in lines) {
      _writeSidebar(line: lineNumber);
      _buffer.write(' ' * _paddingAfterSidebar);
      _writeText(line);
      _buffer.writeln();
      lineNumber++;
    }
  }

  /// 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]).
  void _writeSidebar({int line, String end}) {
    _colorize(() {
      if (line != null) {
        // Add 1 to line to convert from computer-friendly 0-indexed line
        // numbers to human-friendly 1-indexed line numbers.
        _buffer.write((line + 1).toString().padRight(_paddingBeforeSidebar));
      } else {
        _buffer.write(' ' * _paddingBeforeSidebar);
      }
      _buffer.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.
  ///
  /// If [color] is passed, it's used as the color; otherwise, [_color] is used.
  void _colorize(void Function() callback, {String color}) {
    if (_color != null) _buffer.write(color ?? _color);
    callback();
    if (_color != null) _buffer.write(colors.none);
  }
}
