// 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.
library dart_style.src.debug;

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 = new Set<Span>();
  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).where((rule) => rule != null).toSet();

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

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

    var chunk = chunks[index];
    if (chunk.text.length > 70) {
      row.add(chunk.text.substring(0, 70));
    } else {
      row.add(chunk.text);
    }

    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);
    }

    writeIf(predicate, String callback()) {
      if (predicate) {
        row.add(callback());
      } else {
        row.add("");
      }
    }

    if (chunk.rule == null) {
      row.add("");
      row.add("(no rule)");
      row.add("");
    } else {
      writeIf(chunk.rule.cost != 0, () => "\$${chunk.rule.cost}");

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

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

    writeIf(chunk.indent != null && chunk.indent != 0,
        () => "indent ${chunk.indent}");

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

    writeIf(chunk.flushLeft != null && chunk.flushLeft, () => "flush");

    writeIf(chunk.canDivide, () => "divide");

    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 = new 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 = new StringBuffer();
  for (var row in rows) {
    for (var i = 0; i < row.length; i++) {
      var cell = row[i].padRight(rowWidths[i]);

      if (i != 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).where((rule) => rule != null).toSet();

  for (var rule in rules) {
    var constrainedValues = [];
    for (var value = 0; value < rule.numValues; value++) {
      var constraints = [];
      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, int firstLineIndent, SplitSet splits) {
  var buffer = new StringBuffer();

  writeIndent(indent) => buffer.write(gray("| " * (indent ~/ 2)));

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

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

  writeIndent(firstLineIndent);

  for (var i = 0; i < chunks.length - 1; i++) {
    var chunk = chunks[i];
    buffer.write(chunk.text);

    if (splits.shouldSplitAt(i)) {
      for (var j = 0; j < (chunk.isDouble ? 2 : 1); j++) {
        buffer.writeln();
        writeIndent(splits.getColumn(i));
      }
    } else {
      if (chunk.isBlock) writeChunksUnsplit(chunk.block.chunks);

      if (chunk.spaceWhenUnsplit) buffer.write(" ");
    }
  }

  buffer.write(chunks.last.text);
  log(buffer);
}

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