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

/**
 * A test configuration that generates a compact 1-line progress bar. The bar is
 * updated in-place before and after each test is executed. If all test pass,
 * you should only see a couple lines in the terminal. If a test fails, the
 * failure is shown and the progress bar continues to be updated below it.
 */
library unittest.compact_vm_config;

import 'dart:async';
import 'dart:io';
import 'dart:isolate';

import 'unittest.dart';
import 'src/utils.dart';
import 'vm_config.dart';

const String _GREEN = '\u001b[32m';
const String _RED = '\u001b[31m';
const String _NONE = '\u001b[0m';

const int MAX_LINE = 80;

class CompactVMConfiguration extends VMConfiguration {
  // The VM won't shut down if a receive port is open. Use this to make sure
  // we correctly wait for asynchronous tests.
  ReceivePort _receivePort;

  DateTime _start;
  int _pass = 0;
  int _fail = 0;

  void onInit() {
    _receivePort = new ReceivePort();
    // Override and don't call the superclass onInit() to avoid printing the
    // "unittest-suite-..." boilerplate.
  }

  void onStart() {
    _start = new DateTime.now();
  }

  void onTestStart(TestCase test) {
    super.onTestStart(test);
    _progressLine(_start, _pass, _fail, test.description);
  }

  void onTestResult(TestCase test) {
    super.onTestResult(test);
    if (test.result == PASS) {
      _pass++;
      _progressLine(_start, _pass, _fail, test.description);
    } else {
      _fail++;
      _progressLine(_start, _pass, _fail, test.description);
      print('');
      if (test.message != '') {
        print(indent(test.message));
      }

      if (test.stackTrace != null) {
        print(indent(test.stackTrace.toString()));
      }
    }
  }

  void onTestResultChanged(TestCase test) {
    _pass--;
    _fail++;
    _progressLine(_start, _pass, _fail, test.description);
    print('');
    if (test.message != '') {
      print(indent(test.message));
    }

    if (test.stackTrace != null) {
      print(indent(test.stackTrace.toString()));
    }
  }

  void onDone(bool success) {
    // Override and don't call the superclass onDone() to avoid printing the
    // "unittest-suite-..." boilerplate.
    Future.wait([stdout.close(), stderr.close()]).then((_) {
      _receivePort.close();
      exit(success ? 0 : 1);
    });
  }

  void onSummary(int passed, int failed, int errors, List<TestCase> results,
      String uncaughtError) {
    var success = false;
    if (passed == 0 && failed == 0 && errors == 0 && uncaughtError == null) {
      print('\nNo tests ran.');
    } else if (failed == 0 && errors == 0 && uncaughtError == null) {
      _progressLine(_start, _pass, _fail, 'All tests passed!', _NONE);
      print('');
      success = true;
    } else {
      _progressLine(_start, _pass, _fail, 'Some tests failed.', _RED);
      print('');
      if (uncaughtError != null) {
        print('Top-level uncaught error: $uncaughtError');
      }
      print('$passed PASSED, $failed FAILED, $errors ERRORS');
    }
  }

  int _lastLength = 0;

  final int _nonVisiblePrefix = 1 + _GREEN.length + _NONE.length;

  void _progressLine(DateTime startTime, int passed, int failed, String message,
      [String color = _NONE]) {
    var duration = (new DateTime.now()).difference(startTime);
    var buffer = new StringBuffer();
    // \r moves back to the beginning of the current line.
    buffer.write('\r${_timeString(duration)} ');
    buffer.write(_GREEN);
    buffer.write('+');
    buffer.write(passed);
    buffer.write(_NONE);
    if (failed != 0) {
      buffer.write(_RED);
      buffer.write(' -');
      buffer.write(failed);
      buffer.write(_NONE);
    }
    buffer.write(': ');
    buffer.write(color);

    // Ensure the line fits under MAX_LINE. [buffer] includes the color escape
    // sequences too. Because these sequences are not visible characters, we
    // make sure they are not counted towards the limit.
    int nonVisible = _nonVisiblePrefix + color.length  +
        (failed != 0 ? (_RED.length + _NONE.length) : 0);
    int len = buffer.length - nonVisible;
    var mx = MAX_LINE - len;
    buffer.write(_snippet(message, MAX_LINE - len));
    buffer.write(_NONE);

    // Pad the rest of the line so that it looks erased.
    len = buffer.length - nonVisible - _NONE.length;
    if (len > _lastLength) {
      _lastLength = len;
    } else {
      while (len < _lastLength) {
        buffer.write(' ');
        _lastLength--;
      }
    }
    stdout.write(buffer.toString());
  }

  String _padTime(int time) =>
    (time == 0) ? '00' : ((time < 10) ? '0$time' : '$time');

  String _timeString(Duration duration) {
    var min = duration.inMinutes;
    var sec = duration.inSeconds % 60;
    return '${_padTime(min)}:${_padTime(sec)}';
  }

  String _snippet(String text, int maxLength) {
    // Return the full message if it fits
    if (text.length <= maxLength) return text;

    // If we can fit the first and last three words, do so.
    var words = text.split(' ');
    if (words.length > 1) {
      int i = words.length;
      var len = words.first.length + 4;
      do {
        len += 1 + words[--i].length;
      } while (len <= maxLength && i > 0);
      if (len > maxLength || i == 0) i++;
      if (i < words.length - 4) {
        // Require at least 3 words at the end.
        var buffer = new StringBuffer();
        buffer.write(words.first);
        buffer.write(' ...');
        for (; i < words.length; i++) {
          buffer.write(' ');
          buffer.write(words[i]);
        }
        return buffer.toString();
      }
    }

    // Otherwise truncate to return the trailing text, but attempt to start at
    // the beginning of a word.
    var res = text.substring(text.length - maxLength + 4);
    var firstSpace = res.indexOf(' ');
    if (firstSpace > 0) {
      res = res.substring(firstSpace);
    }
    return '...$res';
  }
}

void useCompactVMConfiguration() {
  // If the test is running on the Dart buildbots, we don't want to use this
  // config since it's output may not be what the bots expect.
  if (Platform.environment['LOGNAME'] == 'chrome-bot') {
    return;
  }

  unittestConfiguration = _singleton;
}

final _singleton = new CompactVMConfiguration();
