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

/// Internal debugging utilities.
import 'dart:math' as math;

import 'chunk.dart';
import 'line_splitting/rule_set.dart';

/// Set this to `true` to turn on diagnostic output while building chunks.
bool traceChunkBuilder = false;

/// Set this to `true` to turn on diagnostic output while writing lines.
bool traceLineWriter = false;

/// Set this to `true` to turn on diagnostic output while line splitting.
bool traceSplitter = false;

bool useAnsiColors = false;

const unicodeSection = '\u00a7';
const unicodeMidDot = '\u00b7';

/// The whitespace prefixing each line of output.
String _indent = '';

void indent() {
  _indent = '  $_indent';
}

void unindent() {
  _indent = _indent.substring(2);
}

/// Constants for ANSI color escape codes.
final _gray = _color('\u001b[1;30m');
final _green = _color('\u001b[32m');
final _none = _color('\u001b[0m');
final _bold = _color('\u001b[1m');

/// Prints [message] to stdout with each line correctly indented.
void log([message]) {
  if (message == null) {
    print('');
    return;
  }

  print(_indent + message.toString().replaceAll('\n', '\n$_indent'));
}

/// Wraps [message] in gray ANSI escape codes if enabled.
String gray(message) => '$_gray$message$_none';

/// Wraps [message] in green ANSI escape codes if enabled.
String green(message) => '$_green$message$_none';

/// Wraps [message] in bold ANSI escape codes if enabled.
String bold(message) => '$_bold$message$_none';

/// Prints [chunks] to stdout, one chunk per line, with detailed information
/// about each chunk.
void dumpChunks(int start, List<Chunk> chunks) {
  if (chunks.skip(start).isEmpty) return;

  // Show the spans as vertical bands over their range (unless there are too
  // many).
  var spanSet = <Span>{};
  void addSpans(List<Chunk> chunks) {
    for (var chunk in chunks) {
      spanSet.addAll(chunk.spans);

      if (chunk.isBlock) addSpans(chunk.block.chunks);
    }
  }

  addSpans(chunks);

  var spans = spanSet.toList();
  var rules = chunks.map((chunk) => chunk.rule).toSet();

  var rows = <List<String>>[];

  void addChunk(List<Chunk> chunks, String prefix, int index) {
    var row = <String>[];
    row.add('$prefix$index:');

    var chunk = chunks[index];

    void writeIf(predicate, String Function() callback) {
      if (predicate) {
        row.add(callback());
      } else {
        row.add('');
      }
    }

    var rule = chunk.rule;
    writeIf(rule.cost != 0, () => '\$${rule.cost}');

    var ruleString = rule.toString();
    if (rule.isHardened) ruleString += '!';
    row.add(ruleString);

    var constrainedRules = rule.constrainedRules.toSet().intersection(rules);
    writeIf(
        constrainedRules.isNotEmpty, () => "-> ${constrainedRules.join(" ")}");

    var properties = [
      if (chunk.flushLeft) 'fl',
      if (chunk.isDouble) '2x',
      if (chunk.spaceWhenUnsplit) 'sp',
      if (chunk.canDivide) 'dv',
    ].join(' ');
    row.add(properties);

    writeIf(chunk.indent != 0, () => 'indent ${chunk.indent}');
    writeIf(chunk.nesting.indent != 0, () => 'nest ${chunk.nesting}');

    if (spans.length <= 20) {
      var spanBars = '';
      for (var span in spans) {
        if (chunk.spans.contains(span)) {
          if (index == 0 || !chunks[index - 1].spans.contains(span)) {
            if (span.cost == 1) {
              spanBars += '╓';
            } else {
              spanBars += span.cost.toString();
            }
          } else {
            spanBars += '║';
          }
        } else {
          if (index > 0 && chunks[index - 1].spans.contains(span)) {
            spanBars += '╙';
          } else {
            spanBars += ' ';
          }
        }
      }
      row.add(spanBars);
    }

    if (chunk.text.length > 70) {
      row.add(chunk.text.substring(0, 70));
    } else {
      row.add(chunk.text);
    }

    rows.add(row);

    if (chunk.isBlock) {
      for (var j = 0; j < chunk.block.chunks.length; j++) {
        addChunk(chunk.block.chunks, '$prefix$index.', j);
      }
    }
  }

  for (var i = start; i < chunks.length; i++) {
    addChunk(chunks, '', i);
  }

  var rowWidths = List.filled(rows.first.length, 0);
  for (var row in rows) {
    for (var i = 0; i < row.length; i++) {
      rowWidths[i] = math.max(rowWidths[i], row[i].length);
    }
  }

  var buffer = StringBuffer();
  for (var row in rows) {
    for (var i = 0; i < row.length; i++) {
      if (rowWidths[i] == 0) continue;

      var cell = row[i].padRight(rowWidths[i]);

      if (i != row.length - 1) cell = gray(cell);

      buffer.write(cell);
      buffer.write('  ');
    }

    buffer.writeln();
  }

  print(buffer.toString());
}

/// Shows all of the constraints between the rules used by [chunks].
void dumpConstraints(List<Chunk> chunks) {
  var rules = chunks.map((chunk) => chunk.rule).toSet();

  for (var rule in rules) {
    var constrainedValues = <String>[];
    for (var value = 0; value < rule.numValues; value++) {
      var constraints = <String>[];
      for (var other in rules) {
        if (rule == other) continue;

        var constraint = rule.constrain(value, other);
        if (constraint != null) {
          constraints.add('$other->$constraint');
        }
      }

      if (constraints.isNotEmpty) {
        constrainedValues.add("$value:(${constraints.join(' ')})");
      }
    }

    log("$rule ${constrainedValues.join(' ')}");
  }
}

/// Convert the line to a [String] representation.
///
/// It will determine how best to split it into multiple lines of output and
/// return a single string that may contain one or more newline characters.
void dumpLines(List<Chunk> chunks, SplitSet splits) {
  var buffer = StringBuffer();

  void writeChunksUnsplit(List<Chunk> chunks) {
    for (var chunk in chunks) {
      if (chunk.spaceWhenUnsplit) buffer.write(' ');
      buffer.write(chunk.text);

      // Recurse into the block.
      if (chunk.isBlock) writeChunksUnsplit(chunk.block.chunks);
    }
  }

  for (var i = 0; i < chunks.length; i++) {
    var chunk = chunks[i];

    if (splits.shouldSplitAt(i)) {
      for (var j = 0; j < (chunk.isDouble ? 2 : 1); j++) {
        buffer.writeln();
        buffer.write(gray('| ' * (splits.getColumn(i) ~/ 2)));
      }
    } else if (chunk.spaceWhenUnsplit) {
      buffer.write(' ');
    }

    buffer.write(chunk.text);

    if (chunk.isBlock && !splits.shouldSplitAt(i)) {
      writeChunksUnsplit(chunk.block.chunks);
    }
  }

  log(buffer);
}

String _color(String ansiEscape) => useAnsiColors ? ansiEscape : '';
