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

part of matcher;

/**
 * Returns a matcher which matches [Iterable]s in which all elements
 * match the given [matcher].
 */
Matcher everyElement(matcher) => new _EveryElement(wrapMatcher(matcher));

class _EveryElement extends _IterableMatcher {
  Matcher _matcher;

  _EveryElement(Matcher this._matcher);

  bool matches(item, Map matchState) {
    if (item is! Iterable) {
      return false;
    }
    var i = 0;
    for (var element in item) {
      if (!_matcher.matches(element, matchState)) {
        addStateInfo(matchState, {'index': i, 'element': element});
        return false;
      }
      ++i;
    }
    return true;
  }

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

  Description describeMismatch(item, Description mismatchDescription,
                               Map matchState, bool verbose) {
    if (matchState['index'] != null) {
      var index = matchState['index'];
      var element = matchState['element'];
      mismatchDescription.add('has value ').addDescriptionOf(element).
          add(' which ');
      var subDescription = new StringDescription();
      _matcher.describeMismatch(element, subDescription,
            matchState['state'], verbose);
      if (subDescription.length > 0) {
        mismatchDescription.add(subDescription);
      } else {
        mismatchDescription.add("doesn't match ");
        _matcher.describe(mismatchDescription);
      }
      mismatchDescription.add(' at index $index');
      return mismatchDescription;
    }
    return super.describeMismatch(item, mismatchDescription,
          matchState, verbose);
  }
}

/**
 * Returns a matcher which matches [Iterable]s in which at least one
 * element matches the given [matcher].
 */
Matcher someElement(matcher) => new _SomeElement(wrapMatcher(matcher));

class _SomeElement extends _IterableMatcher {
  Matcher _matcher;

  _SomeElement(this._matcher);

  bool matches(item, Map matchState) {
    return item.any((e) => _matcher.matches(e, matchState));
  }

  Description describe(Description description) =>
      description.add('some element ').addDescriptionOf(_matcher);
}

/**
 * Returns a matcher which matches [Iterable]s that have the same
 * length and the same elements as [expected], and in the same order.
 * This is equivalent to equals but does not recurse.
 */

Matcher orderedEquals(Iterable expected) => new _OrderedEquals(expected);

class _OrderedEquals extends BaseMatcher {
  final Iterable _expected;
  Matcher _matcher;

  _OrderedEquals(this._expected) {
    _matcher = equals(_expected, 1);
  }

  bool matches(item, Map matchState) =>
      (item is Iterable) && _matcher.matches(item, matchState);

  Description describe(Description description) =>
      description.add('equals ').addDescriptionOf(_expected).add(' ordered');

  Description describeMismatch(item, Description mismatchDescription,
                               Map matchState, bool verbose) {
    if (item is !Iterable) {
      return mismatchDescription.add('is not an Iterable');
    } else {
      return _matcher.describeMismatch(item, mismatchDescription,
          matchState, verbose);
    }
  }
}
/**
 * Returns a matcher which matches [Iterable]s that have the same
 * length and the same elements as [expected], but not necessarily in
 * the same order. Note that this is O(n^2) so should only be used on
 * small objects.
 */
Matcher unorderedEquals(Iterable expected) =>
    new _UnorderedEquals(expected);

class _UnorderedEquals extends BaseMatcher {
  Iterable _expected;

  _UnorderedEquals(Iterable this._expected);

  String _test(item) {
    if (item is !Iterable) {
      return 'not iterable';
    }
    // Check the lengths are the same.
    var expectedLength = _expected.length;
    var actualLength = item.length;
    if (expectedLength > actualLength) {
      return 'has too few elements (${actualLength} < ${expectedLength})';
    } else if (expectedLength < actualLength) {
      return 'has too many elements (${actualLength} > ${expectedLength})';
    }
    List<bool> matched = new List<bool>(actualLength);
    for (var i = 0; i < actualLength; i++) {
      matched[i] = false;
    }
    var expectedPosition = 0;
    for (var expectedElement in _expected) {
      var actualPosition = 0;
      var gotMatch = false;
      for (var actualElement in item) {
        if (!matched[actualPosition]) {
          if (expectedElement == actualElement) {
            matched[actualPosition] = gotMatch = true;
            break;
          }
        }
        ++actualPosition;
      }
      if (!gotMatch) {
        Description reason = new StringDescription();
        reason.add('has no match for element ').
            addDescriptionOf(expectedElement).
            add(' at index ${expectedPosition}');
        return reason.toString();
      }
      ++expectedPosition;
    }
    return null;
  }

  bool matches(item, Map mismatchState) => (_test(item) == null);

  Description describe(Description description) =>
      description.add('equals ').addDescriptionOf(_expected).add(' unordered');

  Description describeMismatch(item, Description mismatchDescription,
                               Map matchState, bool verbose) =>
      mismatchDescription.add(_test(item));
}

/**
 * Iterable matchers match against [Iterable]s. We add this intermediate
 * class to give better mismatch error messages than the base Matcher class.
 */
abstract class _IterableMatcher extends BaseMatcher {
  const _IterableMatcher();
  Description describeMismatch(item, Description mismatchDescription,
                               Map matchState, bool verbose) {
    if (item is! Iterable) {
      return mismatchDescription.
          addDescriptionOf(item).
          add(' not an Iterable');
    } else {
      return super.describeMismatch(item, mismatchDescription, matchState,
        verbose);
    }
  }
}

/**
 * A pairwise matcher for iterable. You can pass an arbitrary [comparator]
 * function that takes an expected and actual argument which will be applied
 * to each pair in order. [description]  should be a meaningful name for
 * the comparator.
 */
Matcher pairwiseCompare(Iterable expected, Function comparator,
    String description) =>
        new _PairwiseCompare(expected, comparator, description);

class _PairwiseCompare extends _IterableMatcher {
  Iterable _expected;
  Function _comparator;
  String _description;

  _PairwiseCompare(this._expected, this._comparator, this._description);

  bool matches(item, Map matchState) {
    if (item is! Iterable) return false;
    if (item.length != _expected.length) return false;
    var iterator = item.iterator;
    var i = 0;
    for (var e in _expected) {
      iterator.moveNext();
      if (!_comparator(e, iterator.current)) {
        addStateInfo(matchState, {'index': i, 'expected': e,
            'actual': iterator.current});
        return false;
      }
      i++;
    }
    return true;
  }
    
  Description describe(Description description) =>
      description.add('pairwise $_description ').addDescriptionOf(_expected);

  Description describeMismatch(item, Description mismatchDescription,
                               Map matchState, bool verbose) {
    if (item is !Iterable) {
      return mismatchDescription.add('is not an Iterable');
    } else if (item.length != _expected.length) {
      return mismatchDescription.
          add('has length ${item.length} instead of ${_expected.length}');
    } else {
      return mismatchDescription.
          add('has ').
          addDescriptionOf(matchState["actual"]).
          add(' which is not $_description ').
          addDescriptionOf(matchState["expected"]).
          add(' at index ${matchState["index"]}');
    }
  }
}

