// 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 = new 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;

  factory Highlighter(SourceSpan span, {color}) {
    if (color == true) color = colors.RED;
    if (color == false) color = null;

    // Normalize [span] to ensure that it's a [SourceSpanWithContext] whose
    // context actually contains its text at the expected column. If it's not,
    // adjust the start and end locations' line and column fields so that the
    // highlighter can assume they match up with the context.
    SourceSpanWithContext newSpan;
    if (span is SourceSpanWithContext &&
        findLineStart(span.context, span.text, span.start.column) != null) {
      newSpan = span;
    } else {
      newSpan = new SourceSpanWithContext(
          new SourceLocation(span.start.offset,
              sourceUrl: span.sourceUrl, line: 0, column: 0),
          new SourceLocation(span.end.offset,
              sourceUrl: span.sourceUrl,
              line: countCodeUnits(span.text, $lf),
              column: _lastColumn(span.text)),
          span.text,
          span.text);
    }

    // Normalize [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.
    if (newSpan.context.endsWith("\n")) {
      var context = newSpan.context.substring(0, newSpan.context.length - 1);

      var text = newSpan.text;
      var start = newSpan.start;
      var end = newSpan.end;
      if (newSpan.text.endsWith("\n") && _isTextAtEndOfContext(newSpan)) {
        text = newSpan.text.substring(0, newSpan.text.length - 1);
        end = new SourceLocation(newSpan.end.offset - 1,
            sourceUrl: newSpan.sourceUrl,
            line: newSpan.end.line - 1,
            column: _lastColumn(text));
        start =
            newSpan.start.offset == newSpan.end.offset ? end : newSpan.start;
      }
      newSpan = new SourceSpanWithContext(start, end, text, context);
    }

    return new Highlighter._(newSpan, color);
  }

  /// Returns the (0-based) column number of the last column of the last line in [text].
  static int _lastColumn(String text) =>
      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.toString().length + 1;

  /// Returns the highlighted span text.
  ///
  /// This method should only be called once.
  String highlight() {
    //if (_span.length == 0 && _span.context.isEmpty) return "";

    _writeSidebar(end: glyph.downEnd);
    _buffer.writeln();

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

    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].
      var 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);
    }

    var lines = context.split("\n");

    // Trim a trailing newline so we don't add an empty line to the end of the
    // highlight.
    if (lines.last.isEmpty && lines.length > 1) lines.removeLast();

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

    _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);
    var 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("┌", "/"));
        _buffer.write(" ");
        _writeText(line);
      });
      _buffer.writeln();
      return;
    }

    _buffer.write(" " * _paddingAfterSidebar);
    _writeText(textBefore);
    var 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.
    var tabsBefore = _countTabs(textBefore);
    var 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);
        _buffer.write(glyph.horizontalLine * (startColumn + 1));
        _buffer.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);
        _buffer.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("└", "\\"));
        _buffer.write(" ");
        _writeText(line);
      });
      _buffer.writeln();
      return;
    }

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

    // Adjust the end column to account for any tabs that were converted to
    // spaces.
    var 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);
      _buffer.write(glyph.horizontalLine * endColumn);
      _buffer.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 callback(), {String color}) {
    if (_color != null) _buffer.write(color ?? _color);
    callback();
    if (_color != null) _buffer.write(colors.NONE);
  }
}
