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

part of unittest;

/**
 * Represents the state for an individual unit test.
 *
 * Create by calling [test] or [solo_test].
 */
class TestCase {
  /** Identifier for this test. */
  final int id;

  /** A description of what the test is specifying. */
  final String description;

  /** The setup function to call before the test, if any. */
  Function setUp;

  /** The teardown function to call after the test, if any. */
  Function tearDown;

  /** The body of the test case. */
  TestFunction testFunction;

  /**
   * Remaining number of callbacks functions that must reach a 'done' state
   * to wait for before the test completes.
   */
  int _callbackFunctionsOutstanding = 0;

  String _message = '';
  /** Error or failure message. */
  String get message => _message;

  String _result;
  /**
   * One of [PASS], [FAIL], [ERROR], or [null] if the test hasn't run yet.
   */
  String get result => _result;

  Trace _stackTrace;
  /** Stack trace associated with this test, or [null] if it succeeded. */
  Trace get stackTrace => _stackTrace;

  /** The group (or groups) under which this test is running. */
  final String currentGroup;

  DateTime _startTime;
  DateTime get startTime => _startTime;

  Duration _runningTime;
  Duration get runningTime => _runningTime;

  bool enabled = true;

  bool _doneTeardown = false;

  Completer _testComplete;

  TestCase._internal(this.id, this.description, this.testFunction)
  : currentGroup = _currentContext.fullName,
    setUp = _currentContext.testSetup,
    tearDown = _currentContext.testTeardown;

  bool get isComplete => !enabled || result != null;

  Function _errorHandler(String stage) => (e) {
    var stack = getAttachedStackTrace(e);
    if (result == null || result == PASS) {
      if (e is TestFailure) {
        fail("$e", stack);
      } else {
        error("$stage failed: Caught $e", stack);
      }
    }
  };

  /**
   * Perform any associated [_setUp] function and run the test. Returns
   * a [Future] that can be used to schedule the next test. If the test runs
   * to completion synchronously, or is disabled, null is returned, to
   * tell unittest to schedule the next test immediately.
   */
  Future _run() {
    if (!enabled) return new Future.value();

    _result = _stackTrace = null;
    _message = '';

    var f = (setUp == null) ? new Future.value() : new Future(setUp);
    return f.catchError(_errorHandler('Setup'))
        .then((_) {
          // Skip the test if setup failed.
          if (result != null) return new Future.value();
          _config.onTestStart(this);
          _startTime = new DateTime.now();
          _runningTime = null;
          ++_callbackFunctionsOutstanding;
          return testFunction();
        })
        .catchError(_errorHandler('Test'))
        .then((_) {
          _markCallbackComplete();
          if (result == null) {
            // Outstanding callbacks exist; we need to return a Future.
            _testComplete = new Completer();
            return _testComplete.future.whenComplete(() {
              if (tearDown != null) {
                return tearDown();
              }
            }).catchError(_errorHandler('Teardown'));
          } else if (tearDown != null) {
            return tearDown();
          }
        })
        .catchError(_errorHandler('Teardown'));
  }

  // Set the results, notify the config, and return true if this
  // is the first time the result is being set.
  void _setResult(String testResult, String messageText, stack) {
    _message = messageText;
    _stackTrace = _getTrace(stack);
    if (result == null) {
      _result = testResult;
      _config.onTestResult(this);
    } else {
      _result = testResult;
      _config.onTestResultChanged(this);
    }
  }

  void _complete(String testResult, [String messageText = '', stack]) {
    if (runningTime == null) {
      // The startTime can be `null` if an error happened during setup. In this
      // case we simply report a running time of 0.
      if (startTime != null) {
        _runningTime = new DateTime.now().difference(startTime);
      } else {
        _runningTime = const Duration(seconds: 0);
      }
    }
    _setResult(testResult, messageText, stack);
    if (_testComplete != null) {
      var t = _testComplete;
      _testComplete = null;
      t.complete(this);
    }
  }

  void pass() {
    _complete(PASS);
  }

  void fail(String messageText, [stack]) {
    if (result != null) {
      String newMessage = (result == PASS)
          ? 'Test failed after initially passing: $messageText'
          : 'Test failed more than once: $messageText';
      // TODO(gram): Should we combine the stack with the old one?
      _complete(ERROR, newMessage, stack);
    } else {
      _complete(FAIL, messageText, stack);
    }
  }

  void error(String messageText, [stack]) {
    _complete(ERROR, messageText, stack);
  }

  void _markCallbackComplete() {
    if (--_callbackFunctionsOutstanding == 0 && !isComplete) {
      pass();
    }
  }
}
