// Copyright (c) 2012, 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 matcher.expect;

import 'core_matchers.dart';
import 'description.dart';
import 'interfaces.dart';
import 'util.dart';

/// The objects thrown by the default failure handler.
class TestFailure extends Error {
  final String message;

  TestFailure(this.message);

  String toString() => message;
}

/// Failed matches are reported using a default IFailureHandler.
/// The default implementation simply throws [TestFailure]s;
/// this can be replaced by some other implementation of
/// IFailureHandler by calling configureExpectHandler.
abstract class FailureHandler {
  /// This handles failures given a textual decription
  void fail(String reason);

  /// This handles failures given the actual [value], the [matcher]
  /// the [reason] (argument from [expect]), some additonal [matchState]
  /// generated by the [matcher], and a verbose flag which controls in
  /// some cases how much [matchState] information is used. It will use
  /// these to create a detailed error message (typically by calling
  /// an [ErrorFormatter]) and then call [fail] with this message.
  void failMatch(actual, Matcher matcher, String reason,
                 Map matchState, bool verbose);
}

/// The ErrorFormatter type is used for functions that
/// can be used to build up error reports upon [expect] failures.
/// There is one built-in implementation ([defaultErrorFormatter])
/// which is used by the default failure handler. If the failure handler
/// is replaced it may be desirable to replace the [stringDescription]
/// error formatter with another.
typedef String ErrorFormatter(actual, Matcher matcher, String reason,
  Map matchState, bool verbose);

/// This Function is used by certain Matchers to catch certain exceptions.
///
/// Some matchers, like those for Futures and exception testing,
/// can fail in asynchronous sections, and throw exceptions.
/// A user of this library will typically want to catch and handle
/// such exceptions. The [wrapAsync] property is a function that
/// can wrap callbacks used by these Matchers so that they can be
/// used safely. For example, the unittest library will set this
/// to be `expectAsync`. By default this is an identity function.
Function wrapAsync = (Function f, [id]) => f;

/// Assert that [actual] matches [matcher].
///
/// This is the main assertion function. [reason] is optional and is typically
/// not supplied, as a reason is generated from the matcher; if [reason]
/// is included it is appended to the reason generated by the matcher.
///
/// [matcher] can be a value in which case it will be wrapped in an
/// [equals] matcher.
///
/// If the assertion fails, then the default behavior is to throw a
/// [TestFailure], but this behavior can be changed by calling
/// [configureExpectFailureHandler] and providing an alternative handler that
/// implements the [IFailureHandler] interface. It is also possible to
/// pass a [failureHandler] to [expect] as a final parameter for fine-
/// grained control.
///
/// In some cases extra diagnostic info can be produced on failure (for
/// example, stack traces on mismatched exceptions). To enable these,
/// [verbose] should be specified as true;
void expect(actual, matcher, {String reason, FailureHandler failureHandler,
            bool verbose : false}) {
  matcher = wrapMatcher(matcher);
  bool doesMatch;
  var matchState = {};
  try {
    doesMatch = matcher.matches(actual, matchState);
  } catch (e, trace) {
    doesMatch = false;
    if (reason == null) {
      reason = '${(e is String) ? e : e.toString()} at $trace';
    }
  }
  if (!doesMatch) {
    if (failureHandler == null) {
      failureHandler = getOrCreateExpectFailureHandler();
    }
    failureHandler.failMatch(actual, matcher, reason, matchState, verbose);
  }
}

void fail(String message, {FailureHandler failureHandler}) {
  if (failureHandler == null) {
    failureHandler = getOrCreateExpectFailureHandler();
  }
  failureHandler.fail(message);
}

// The handler for failed asserts.
FailureHandler _assertFailureHandler = null;

// The default failure handler that throws [TestFailure]s.
class DefaultFailureHandler implements FailureHandler {
  DefaultFailureHandler() {
    if (_assertErrorFormatter == null) {
      _assertErrorFormatter = _defaultErrorFormatter;
    }
  }
  void fail(String reason) {
    throw new TestFailure(reason);
  }
  void failMatch(actual, Matcher matcher, String reason,
      Map matchState, bool verbose) {
    fail(_assertErrorFormatter(actual, matcher, reason, matchState, verbose));
  }
}

/// Changes the default failure handler for [expect].
///
/// [handler] is a reference to the new handler; if this is omitted
/// or null then the failure handler is reset to the default, which
/// throws [TestFailure]s on [expect] assertion failures.
void configureExpectFailureHandler([FailureHandler handler = null]) {
  if (handler == null) {
    handler = new DefaultFailureHandler();
  }
  _assertFailureHandler = handler;
}

FailureHandler getOrCreateExpectFailureHandler() {
  if (_assertFailureHandler == null) {
    configureExpectFailureHandler();
  }
  return _assertFailureHandler;
}

// The error message formatter for failed asserts.
ErrorFormatter _assertErrorFormatter = null;

// The default error formatter implementation.
String _defaultErrorFormatter(actual, Matcher matcher, String reason,
    Map matchState, bool verbose) {
  var description = new StringDescription();
  description.add('Expected: ').addDescriptionOf(matcher).add('\n');
  description.add('  Actual: ').addDescriptionOf(actual).add('\n');

  var mismatchDescription = new StringDescription();
  matcher.describeMismatch(actual, mismatchDescription, matchState, verbose);

  if (mismatchDescription.length > 0) {
    description.add('   Which: ${mismatchDescription}\n');
  }
  if (reason != null) {
    description.add(reason).add('\n');
  }
  return description.toString();
}

/// Changes the failure message formatter for expect().
///
/// [formatter] is a reference to the new formatter; if this is omitted or
/// null then the failure formatter is reset to the default. The new
/// formatter is returned; this allows custom expect handlers to easily
/// get a reference to the default formatter.
ErrorFormatter configureExpectFormatter([ErrorFormatter formatter = null]) {
  if (formatter == null) {
    formatter = _defaultErrorFormatter;
  }
  return _assertErrorFormatter = formatter;
}
