// Copyright (c) 2015, 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.

library dart_style.example.format;

import 'dart:io';
import 'dart:mirrors';

import 'package:path/path.dart' as p;

import 'package:dart_style/dart_style.dart';
import 'package:dart_style/src/debug.dart' as debug;

void main(List<String> args) {
  // Enable debugging so you can see some of the formatter's internal state.
  // Normal users do not do this.
  debug.traceChunkBuilder = true;
  debug.traceLineWriter = true;
  debug.traceSplitter = true;
  debug.useAnsiColors = true;

  formatStmt('a is int????;');
}

void formatStmt(String source, [int pageWidth = 80]) {
  runFormatter(source, pageWidth, isCompilationUnit: false);
}

void formatUnit(String source, [int pageWidth = 80]) {
  runFormatter(source, pageWidth, isCompilationUnit: true);
}

void runFormatter(String source, int pageWidth, {bool isCompilationUnit}) {
  try {
    var formatter = DartFormatter(pageWidth: pageWidth);

    var result;
    if (isCompilationUnit) {
      result = formatter.format(source);
    } else {
      result = formatter.formatStatement(source);
    }

    drawRuler('before', pageWidth);
    print(source);
    drawRuler('after', pageWidth);
    print(result);
  } on FormatterException catch (error) {
    print(error.message());
  }
}

void drawRuler(String label, int width) {
  var padding = ' ' * (width - label.length - 1);
  print('$label:$padding|');
}

/// Runs the formatter test starting on [line] at [path] inside the "test"
/// directory.
void runTest(String path, int line) {
  var indentPattern = RegExp(r'^\(indent (\d+)\)\s*');

  // Locate the "test" directory. Use mirrors so that this works with the test
  // package, which loads this suite into an isolate.
  var testDir = p.join(
      p.dirname(currentMirrorSystem()
          .findLibrary(#dart_style.example.format)
          .uri
          .path),
      '../test');

  var lines = File(p.join(testDir, path)).readAsLinesSync();

  // The first line may have a "|" to indicate the page width.
  var pageWidth = 80;
  if (lines[0].endsWith('|')) {
    pageWidth = lines[0].indexOf('|');
    lines = lines.skip(1).toList();
  }

  var i = 0;
  while (i < lines.length) {
    var description = lines[i++].replaceAll('>>>', '').trim();

    // Let the test specify a leading indentation. This is handy for
    // regression tests which often come from a chunk of nested code.
    var leadingIndent = 0;
    var indentMatch = indentPattern.firstMatch(description);
    if (indentMatch != null) {
      leadingIndent = int.parse(indentMatch[1]);
      description = description.substring(indentMatch.end);
    }

    if (description == '') {
      description = 'line ${i + 1}';
    } else {
      description = 'line ${i + 1}: $description';
    }
    var startLine = i + 1;

    var input = '';
    while (!lines[i].startsWith('<<<')) {
      input += lines[i++] + '\n';
    }

    var expectedOutput = '';
    while (++i < lines.length && !lines[i].startsWith('>>>')) {
      expectedOutput += lines[i] + '\n';
    }

    if (line != startLine) continue;

    var isCompilationUnit = p.extension(path) == '.unit';

    var inputCode =
        _extractSelection(input, isCompilationUnit: isCompilationUnit);

    var expected =
        _extractSelection(expectedOutput, isCompilationUnit: isCompilationUnit);

    var formatter = DartFormatter(pageWidth: pageWidth, indent: leadingIndent);

    var actual = formatter.formatSource(inputCode);

    // The test files always put a newline at the end of the expectation.
    // Statements from the formatter (correctly) don't have that, so add
    // one to line up with the expected result.
    var actualText = actual.text;
    if (!isCompilationUnit) actualText += '\n';

    print('$path $description');
    drawRuler('before', pageWidth);
    print(input);
    if (actualText == expected.text) {
      drawRuler('result', pageWidth);
      print(actualText);
    } else {
      print('FAIL');
      drawRuler('expected', pageWidth);
      print(expected.text);
      drawRuler('actual', pageWidth);
      print(actualText);
    }
  }
}

/// Given a source string that contains ‹ and › to indicate a selection, returns
/// a [SourceCode] with the text (with the selection markers removed) and the
/// correct selection range.
SourceCode _extractSelection(String source, {bool isCompilationUnit = false}) {
  var start = source.indexOf('‹');
  source = source.replaceAll('‹', '');

  var end = source.indexOf('›');
  source = source.replaceAll('›', '');

  return SourceCode(source,
      isCompilationUnit: isCompilationUnit,
      selectionStart: start == -1 ? null : start,
      selectionLength: end == -1 ? null : end - start);
}
