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


/**
 * Returns a matcher that matches empty strings, maps or collections.
 */
const Matcher isEmpty = const _Empty();

class _Empty extends BaseMatcher {
  const _Empty();
  bool matches(item, MatchState matchState) {
    if (item is Map || item is Collection) {
      return item.isEmpty;
    } else if (item is String) {
      return item.length == 0;
    } else {
      return false;
    }
  }
  Description describe(Description description) =>
      description.add('empty');
}

/** A matcher that matches any null value. */
const Matcher isNull = const _IsNull();

/** A matcher that matches any non-null value. */
const Matcher isNotNull = const _IsNotNull();

class _IsNull extends BaseMatcher {
  const _IsNull();
  bool matches(item, MatchState matchState) => item == null;
  Description describe(Description description) =>
      description.add('null');
}

class _IsNotNull extends BaseMatcher {
  const _IsNotNull();
  bool matches(item, MatchState matchState) => item != null;
  Description describe(Description description) =>
      description.add('not null');
}

/** A matcher that matches the Boolean value true. */
const Matcher isTrue = const _IsTrue();

/** A matcher that matches anything except the Boolean value true. */
const Matcher isFalse = const _IsFalse();

class _IsTrue extends BaseMatcher {
  const _IsTrue();
  bool matches(item, MatchState matchState) => item == true;
  Description describe(Description description) =>
      description.add('true');
}

class _IsFalse extends BaseMatcher {
  const _IsFalse();
  bool matches(item, MatchState matchState) => item != true;
  Description describe(Description description) =>
      description.add('false');
}

/**
 * Returns a matches that matches if the value is the same instance
 * as [object] (`===`).
 */
Matcher same(expected) => new _IsSameAs(expected);

class _IsSameAs extends BaseMatcher {
  final _expected;
  const _IsSameAs(this._expected);
  bool matches(item, MatchState matchState) => item === _expected;
  // If all types were hashable we could show a hash here.
  Description describe(Description description) =>
      description.add('same instance as ').addDescriptionOf(_expected);
}

/**
 * Returns a matcher that does a deep recursive match. This only works
 * with scalars, Maps and Iterables. To handle cyclic structures a
 * recursion depth [limit] can be provided. The default limit is 100.
 */
Matcher equals(expected, [limit=100]) =>
    new _DeepMatcher(expected, limit);

class _DeepMatcher extends BaseMatcher {
  final _expected;
  final int _limit;
  var count;

  _DeepMatcher(this._expected, [limit = 1000]) : this._limit = limit;

  String _compareIterables(expected, actual, matcher, depth) {
    if (actual is !Iterable) {
      return 'is not Iterable';
    }
    var expectedIterator = expected.iterator();
    var actualIterator = actual.iterator();
    var position = 0;
    String reason = null;
    while (reason == null) {
      if (expectedIterator.hasNext) {
        if (actualIterator.hasNext) {
          Description r = matcher(expectedIterator.next(),
                           actualIterator.next(),
                           'mismatch at position ${position}',
                           depth);
          if (r != null) reason = r.toString();
          ++position;
        } else {
          reason = 'shorter than expected';
        }
      } else if (actualIterator.hasNext) {
        reason = 'longer than expected';
      } else {
        return null;
      }
    }
    return reason;
  }

  Description _recursiveMatch(expected, actual, String location, int depth) {
    Description reason = null;
    // If _limit is 1 we can only recurse one level into object.
    bool canRecurse = depth == 0 || _limit > 1;
    if (expected == actual) {
      // Do nothing.
    } else if (depth > _limit) {
      reason = new StringDescription('recursion depth limit exceeded');
    } else {
      if (expected is Iterable && canRecurse) {
        String r = _compareIterables(expected, actual,
          _recursiveMatch, depth+1);
        if (r != null) reason = new StringDescription(r);
      } else if (expected is Map && canRecurse) {
        if (actual is !Map) {
          reason = new StringDescription('expected a map');
        } else if (expected.length != actual.length) {
          reason = new StringDescription('different map lengths');
        } else {
          for (var key in expected.keys) {
            if (!actual.containsKey(key)) {
              reason = new StringDescription('missing map key ');
              reason.addDescriptionOf(key);
              break;
            }
            reason = _recursiveMatch(expected[key], actual[key],
                'with key <${key}> ${location}', depth+1);
            if (reason != null) {
              break;
            }
          }
        }
      } else {
        // If we have recursed, show the expected value too; if not,
        // expect() will show it for us.
        reason = new StringDescription();
        if (depth > 1) {
          reason.add('expected ').addDescriptionOf(expected).add(' but was ').
              addDescriptionOf(actual);
        } else {
          reason.add('was ').addDescriptionOf(actual);
        }
      }
    }
    if (reason != null && location.length > 0) {
      reason.add(' ').add(location);
    }
    return reason;
  }

  String _match(expected, actual) {
    Description reason = _recursiveMatch(expected, actual, '', 0);
    return reason == null ? null : reason.toString();
  }

  // TODO(gram) - see if we can make use of matchState here to avoid
  // recursing again in describeMismatch.
  bool matches(item, MatchState matchState) => _match(_expected, item) == null;

  Description describe(Description description) =>
    description.addDescriptionOf(_expected);

  Description describeMismatch(item, Description mismatchDescription,
                               MatchState matchState, bool verbose) =>
    mismatchDescription.add(_match(_expected, item));
}

/** A matcher that matches any value. */
const Matcher anything = const _IsAnything();

class _IsAnything extends BaseMatcher {
  const _IsAnything();
  bool matches(item, MatchState matchState) => true;
  Description describe(Description description) =>
      description.add('anything');
}

/**
 * Returns a matcher that matches if an object is an instance
 * of [type] (or a subtype).
 *
 * As types are not first class objects in Dart we can only
 * approximate this test by using a generic wrapper class.
 *
 * For example, to test whether 'bar' is an instance of type
 * 'Foo', we would write:
 *
 *     expect(bar, new isInstanceOf<Foo>());
 *
 * To get better error message, supply a name when creating the
 * Type wrapper; e.g.:
 *
 *     expect(bar, new isInstanceOf<Foo>('Foo'));
 */
class isInstanceOf<T> extends BaseMatcher {
  final String _name;
  const isInstanceOf([name = 'specified type']) : this._name = name;
  bool matches(obj, MatchState matchState) => obj is T;
  // The description here is lame :-(
  Description describe(Description description) =>
      description.add('an instance of ${_name}');
}

/**
 * This can be used to match two kinds of objects:
 *
 *   * A [Function] that throws an exception when called. The function cannot
 *     take any arguments. If you want to test that a function expecting
 *     arguments throws, wrap it in another zero-argument function that calls
 *     the one you want to test.
 *
 *   * A [Future] that completes with an exception. Note that this creates an
 *     asynchronous expectation. The call to `expect()` that includes this will
 *     return immediately and execution will continue. Later, when the future
 *     completes, the actual expectation will run.
 */
const Matcher throws = const Throws();

/**
 * This can be used to match two kinds of objects:
 *
 *   * A [Function] that throws an exception when called. The function cannot
 *     take any arguments. If you want to test that a function expecting
 *     arguments throws, wrap it in another zero-argument function that calls
 *     the one you want to test.
 *
 *   * A [Future] that completes with an exception. Note that this creates an
 *     asynchronous expectation. The call to `expect()` that includes this will
 *     return immediately and execution will continue. Later, when the future
 *     completes, the actual expectation will run.
 *
 * In both cases, when an exception is thrown, this will test that the exception
 * object matches [matcher]. If [matcher] is not an instance of [Matcher], it
 * will implicitly be treated as `equals(matcher)`.
 */
Matcher throwsA(matcher) => new Throws(wrapMatcher(matcher));

/**
 * A matcher that matches a function call against no exception.
 * The function will be called once. Any exceptions will be silently swallowed.
 * The value passed to expect() should be a reference to the function.
 * Note that the function cannot take arguments; to handle this
 * a wrapper will have to be created.
 */
const Matcher returnsNormally = const _ReturnsNormally();

class Throws extends BaseMatcher {
  final Matcher _matcher;

  const Throws([Matcher matcher]) :
    this._matcher = matcher;

  bool matches(item, MatchState matchState) {
    if (item is Future) {
      // Queue up an asynchronous expectation that validates when the future
      // completes.
      item.onComplete(expectAsync1((future) {
        if (future.hasValue) {
          expect(false, isTrue,
              "Expected future to fail, but succeeded with '${future.value}'.");
        } else if (_matcher != null) {
          var reason;
          if (future.stackTrace != null) {
            var stackTrace = future.stackTrace.toString();
            stackTrace = "  ${stackTrace.replaceAll("\n", "\n  ")}";
            reason = "Actual exception trace:\n$stackTrace";
          }
          expect(future.exception, _matcher, reason);
        }
      }));

      // It hasn't failed yet.
      return true;
    }

    try {
      item();
      return false;
    } catch (e, s) {
      if (_matcher == null ||_matcher.matches(e, matchState)) {
        return true;
      } else {
        matchState.state = {
            'exception' :e,
            'stack': s
        };
        return false;
      }
    }
  }

  Description describe(Description description) {
    if (_matcher == null) {
      return description.add("throws an exception");
    } else {
      return description.add('throws an exception which matches ').
          addDescriptionOf(_matcher);
    }
  }

  Description describeMismatch(item, Description mismatchDescription,
                               MatchState matchState,
                               bool verbose) {
    if (_matcher == null ||  matchState.state == null) {
      return mismatchDescription.add(' no exception');
    } else {
      mismatchDescription.
          add(' exception ').addDescriptionOf(matchState.state['exception']);
      if (verbose) {
          mismatchDescription.add(' at ').
          add(matchState.state['stack'].toString());
      }
       mismatchDescription.add(' does not match ').addDescriptionOf(_matcher);
       return mismatchDescription;
    }
  }
}

class _ReturnsNormally extends BaseMatcher {
  const _ReturnsNormally();

  bool matches(f, MatchState matchState) {
    try {
      f();
      return true;
    } catch (e, s) {
      matchState.state = {
          'exception' : e,
          'stack': s
      };
      return false;
    }
  }

  Description describe(Description description) =>
      description.add("return normally");

  Description describeMismatch(item, Description mismatchDescription,
                               MatchState matchState,
                               bool verbose) {
      mismatchDescription.add(' threw ').
          addDescriptionOf(matchState.state['exception']);
      if (verbose) {
        mismatchDescription.add(' at ').
        add(matchState.state['stack'].toString());
      }
      return mismatchDescription;
  }
}

/*
 * Matchers for different exception types. Ideally we should just be able to
 * use something like:
 *
 * final Matcher throwsException =
 *     const _Throws(const isInstanceOf<Exception>());
 *
 * Unfortunately instanceOf is not working with dart2js.
 *
 * Alternatively, if static functions could be used in const expressions,
 * we could use:
 *
 * bool _isException(x) => x is Exception;
 * final Matcher isException = const _Predicate(_isException, "Exception");
 * final Matcher throwsException = const _Throws(isException);
 *
 * But currently using static functions in const expressions is not supported.
 * For now the only solution for all platforms seems to be separate classes
 * for each exception type.
 */

abstract class ExceptionMatcher extends BaseMatcher {
  final String _name;
  const ExceptionMatcher(this._name);
  Description describe(Description description) =>
      description.add(_name);
}

/** A matcher for FormatExceptions. */
const isFormatException = const _FormatException();

/** A matcher for functions that throw FormatException */
const Matcher throwsFormatException =
    const Throws(isFormatException);

class _FormatException extends ExceptionMatcher {
  const _FormatException() : super("FormatException");
  bool matches(item, MatchState matchState) => item is FormatException;
}

/** A matcher for Exceptions. */
const isException = const _Exception();

/** A matcher for functions that throw Exception */
const Matcher throwsException = const Throws(isException);

class _Exception extends ExceptionMatcher {
  const _Exception() : super("Exception");
  bool matches(item, MatchState matchState) => item is Exception;
}

/** A matcher for ArgumentErrors. */
const isArgumentError = const _ArgumentError();

/** A matcher for functions that throw ArgumentError */
const Matcher throwsArgumentError =
    const Throws(isArgumentError);

class _ArgumentError extends ExceptionMatcher {
  const _ArgumentError() : super("ArgumentError");
  bool matches(item, MatchState matchState) => item is ArgumentError;
}

/** A matcher for IllegalJSRegExpExceptions. */
const isIllegalJSRegExpException = const _IllegalJSRegExpException();

/** A matcher for functions that throw IllegalJSRegExpException */
const Matcher throwsIllegalJSRegExpException =
    const Throws(isIllegalJSRegExpException);

class _IllegalJSRegExpException extends ExceptionMatcher {
  const _IllegalJSRegExpException() : super("IllegalJSRegExpException");
  bool matches(item, MatchState matchState) => item is IllegalJSRegExpException;
}

/** A matcher for IndexOutOfRangeExceptions. */
const isIndexOutOfRangeException = const _IndexOutOfRangeException();

/** A matcher for functions that throw IndexOutOfRangeException */
const Matcher throwsIndexOutOfRangeException =
    const Throws(isIndexOutOfRangeException);

class _IndexOutOfRangeException extends ExceptionMatcher {
  const _IndexOutOfRangeException() : super("IndexOutOfRangeException");
  bool matches(item, MatchState matchState) => item is IndexOutOfRangeException;
}

/** A matcher for NoSuchMethodErrors. */
const isNoSuchMethodError = const _NoSuchMethodError();

/** A matcher for functions that throw NoSuchMethodError */
const Matcher throwsNoSuchMethodError =
    const Throws(isNoSuchMethodError);

class _NoSuchMethodError extends ExceptionMatcher {
  const _NoSuchMethodError() : super("NoSuchMethodError");
  bool matches(item, MatchState matchState) => item is NoSuchMethodError;
}

/** A matcher for NotImplementedExceptions. */
const isNotImplementedException = const _NotImplementedException();

/** A matcher for functions that throw Exception */
const Matcher throwsNotImplementedException =
    const Throws(isNotImplementedException);

class _NotImplementedException extends ExceptionMatcher {
  const _NotImplementedException() : super("NotImplementedException");
  bool matches(item, MatchState matchState) => item is NotImplementedException;
}

/** A matcher for NullPointerExceptions. */
const isNullPointerException = const _NullPointerException();

/** A matcher for functions that throw NotNullPointerException */
const Matcher throwsNullPointerException =
    const Throws(isNullPointerException);

class _NullPointerException extends ExceptionMatcher {
  const _NullPointerException() : super("NullPointerException");
  bool matches(item, MatchState matchState) => item is NullPointerException;
}

/** A matcher for UnsupportedErrors. */
const isUnsupportedError = const _UnsupportedError();

/** A matcher for functions that throw UnsupportedError */
const Matcher throwsUnsupportedError =
    const Throws(isUnsupportedError);

class _UnsupportedError extends ExceptionMatcher {
  const _UnsupportedError() :
      super("UnsupportedError");
  bool matches(item, MatchState matchState) =>
      item is UnsupportedError;
}

/**
 * Returns a matcher that matches if an object has a length property
 * that matches [matcher].
 */
Matcher hasLength(matcher) =>
    new _HasLength(wrapMatcher(matcher));

class _HasLength extends BaseMatcher {
  final Matcher _matcher;
  const _HasLength([Matcher matcher = null]) : this._matcher = matcher;

  bool matches(item, MatchState matchState) {
    return _matcher.matches(item.length, matchState);
  }

  Description describe(Description description) =>
    description.add('an object with length of ').
        addDescriptionOf(_matcher);

  Description describeMismatch(item, Description mismatchDescription,
                               MatchState matchState, bool verbose) {
    super.describeMismatch(item, mismatchDescription, matchState, verbose);
    try {
      // We want to generate a different description if there is no length
      // property. This is harmless code that will throw if no length property
      // but subtle enough that an optimizer shouldn't strip it out.
      if (item.length * item.length >= 0) {
        return mismatchDescription.add(' with length of ').
            addDescriptionOf(item.length);
      }
    } catch (e) {
      return mismatchDescription.add(' has no length property');
    }
  }
}

/**
 * Returns a matcher that matches if the match argument contains
 * the expected value. For [String]s this means substring matching;
 * for [Map]s is means the map has the key, and for [Collection]s it
 * means the collection has a matching element. In the case of collections,
 * [expected] can itself be a matcher.
 */
Matcher contains(expected) => new _Contains(expected);

class _Contains extends BaseMatcher {

  final _expected;

  const _Contains(this._expected);

  bool matches(item, MatchState matchState) {
    if (item is String) {
      return item.indexOf(_expected) >= 0;
    } else if (item is Collection) {
      if (_expected is Matcher) {
        return item.some((e) => _expected.matches(e, matchState));
      } else {
        return item.some((e) => e == _expected);
      }
    } else if (item is Map) {
      return item.containsKey(_expected);
    }
    return false;
  }

  Description describe(Description description) =>
      description.add('contains ').addDescriptionOf(_expected);
}

/**
 * Returns a matcher that matches if the match argument is in
 * the expected value. This is the converse of [contains].
 */
Matcher isIn(expected) => new _In(expected);

class _In extends BaseMatcher {

  final _expected;

  const _In(this._expected);

  bool matches(item, MatchState matchState) {
    if (_expected is String) {
      return _expected.indexOf(item) >= 0;
    } else if (_expected is Collection) {
      return _expected.some((e) => e == item);
    } else if (_expected is Map) {
      return _expected.containsKey(item);
    }
    return false;
  }

  Description describe(Description description) =>
      description.add('is in ').addDescriptionOf(_expected);
}

/**
 * Returns a matcher that uses an arbitrary function that returns
 * true or false for the actual value.
 */
Matcher predicate(f, {description: 'satisfies function'}) =>
    new _Predicate(f, description);

class _Predicate extends BaseMatcher {

  final _matcher;
  final String _description;

  const _Predicate(this._matcher, this._description);

  bool matches(item, MatchState matchState) => _matcher(item);

  Description describe(Description description) =>
      description.add(_description);
}

/**
 * A useful utility class for implementing other matchers through inheritance.
 * Derived classes should call the base constructor with a feature name and
 * description, and an instance matcher, and should implement the
 * [featureValueOf] abstract method.
 *
 * The feature description will typically describe the item and the feature,
 * while the feature name will just name the feature. For example, we may
 * have a Widget class where each Widget has a price; we could make a
 * FeatureMatcher that can make assertions about prices with:
 *
 *     class HasPrice extends FeatureMatcher {
 *       const HasPrice(matcher) :
 *           super("Widget with price that is", "price", matcher);
 *       featureValueOf(actual) => actual.price;
 *     }
 *
 * and then use this for example like:
 *
 *      expect(inventoryItem, new HasPrice(greaterThan(0)));
 */
abstract class CustomMatcher extends BaseMatcher {
  final String _featureDescription;
  final String _featureName;
  final Matcher _matcher;

  const CustomMatcher(this._featureDescription, this._featureName,
      this._matcher);

  /** Implement this to extract the interesting feature.*/
  featureValueOf(actual);

  bool matches(item, MatchState matchState) {
    var f = featureValueOf(item);
    if (_matcher.matches(f, matchState)) return true;
    matchState.state = { 'innerState': matchState.state, 'feature': f };
    return false;
  }

  Description describe(Description description) =>
      description.add(_featureDescription).add(' ').addDescriptionOf(_matcher);

  Description describeMismatch(item, Description mismatchDescription,
                               MatchState matchState, bool verbose) {
    mismatchDescription.add(_featureName).add(' ');
    _matcher.describeMismatch(matchState.state['feature'], mismatchDescription,
        matchState.state['innerState'], verbose);
    return mismatchDescription;
  }
}
