// 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 if the match argument is a string and
 * is equal to [value] when compared case-insensitively.
 */
Matcher equalsIgnoringCase(String value) => new _IsEqualIgnoringCase(value);

class _IsEqualIgnoringCase extends _StringMatcher {
  final String _value;
  String _matchValue;

  _IsEqualIgnoringCase(this._value) {
    _matchValue = _value.toLowerCase();
  }

  bool matches(item, MatchState mismatchState) =>
      item is String && _matchValue == item.toLowerCase();

  Description describe(Description description) =>
      description.addDescriptionOf(_value).add(' ignoring case');
}

/**
 * Returns a matcher which matches if the match argument is a string and
 * is equal to [value] when compared with all runs of whitespace
 * collapsed to single spaces and leading and trailing whitespace removed.
 *
 * For example, `equalsIgnoringCase("hello world")` will match
 * "hello   world", "  hello world" and "hello world  ".
 */
Matcher equalsIgnoringWhitespace(_string) =>
    new _IsEqualIgnoringWhitespace(_string);

class _IsEqualIgnoringWhitespace extends _StringMatcher {
  final String _value;
  String _matchValue;

  _IsEqualIgnoringWhitespace(this._value) {
    _matchValue = collapseWhitespace(_value);
  }

  bool matches(item, MatchState matchState) =>
      item is String && _matchValue == collapseWhitespace(item);

  Description describe(Description description) =>
    description.addDescriptionOf(_matchValue).add(' ignoring whitespace');

  Description describeMismatch(item, Description mismatchDescription,
                               MatchState matchState, bool verbose) {
    if (item is String) {
      return mismatchDescription.add('was ').
          addDescriptionOf(collapseWhitespace(item));
    } else {
      return super.describeMismatch(item, mismatchDescription,
          matchState, verbose);
    }
  }
}

/**
 * Utility function to collapse whitespace runs to single spaces
 * and strip leading/trailing whitespace.
 */
String collapseWhitespace(_string) {
  bool isWhitespace(String ch) => (' \n\r\t'.indexOf(ch) >= 0);
  StringBuffer result = new StringBuffer();
  bool skipSpace = true;
  for (var i = 0; i < _string.length; i++) {
    var character = _string[i];
    if (isWhitespace(character)) {
      if (!skipSpace) {
        result.write(' ');
        skipSpace = true;
      }
    } else {
      result.write(character);
      skipSpace = false;
    }
  }
  return result.toString().trim();
}

/**
 * Returns a matcher that matches if the match argument is a string and
 * starts with [prefixString].
 */
Matcher startsWith(String prefixString) => new _StringStartsWith(prefixString);

class _StringStartsWith extends _StringMatcher {
  final String _prefix;

  const _StringStartsWith(this._prefix);

  bool matches(item, MatchState matchState) =>
      item is String && item.startsWith(_prefix);

  Description describe(Description description) =>
      description.add('a string starting with ').addDescriptionOf(_prefix);
}

/**
 * Returns a matcher that matches if the match argument is a string and
 * ends with [suffixString].
 */
Matcher endsWith(String suffixString) => new _StringEndsWith(suffixString);

class _StringEndsWith extends _StringMatcher {

  final String _suffix;

  const _StringEndsWith(this._suffix);

  bool matches(item, MatchState matchState) =>
      item is String && item.endsWith(_suffix);

  Description describe(Description description) =>
      description.add('a string ending with ').addDescriptionOf(_suffix);
}

/**
 * Returns a matcher that matches if the match argument is a string and
 * contains a given list of [substrings] in relative order.
 *
 * For example, `stringContainsInOrder(["a", "e", "i", "o", "u"])` will match
 * "abcdefghijklmnopqrstuvwxyz".
 */

Matcher stringContainsInOrder(substrings) =>
    new _StringContainsInOrder(substrings);

class _StringContainsInOrder extends _StringMatcher {

  final List<String> _substrings;

  const _StringContainsInOrder(this._substrings);

  bool matches(item, MatchState matchState) {
    if (!(item is String)) {
      return false;
    }
    var from_index = 0;
    for (var s in _substrings) {
      from_index = item.indexOf(s, from_index);
      if (from_index < 0)
        return false;
    }
    return true;
  }

  Description describe(Description description) =>
      description.addAll('a string containing ', ', ', ' in order',
                                                  _substrings);
}

/**
 * Returns a matcher that matches if the match argument is a string and
 * matches the regular expression given by [re]. [re] can be a RegExp
 * instance or a string; in the latter case it will be used to create
 * a RegExp instance.
 */
Matcher matches(re) => new _MatchesRegExp(re);

class _MatchesRegExp extends _StringMatcher {
  RegExp _regexp;

  _MatchesRegExp(re) {
    if (re is String) {
      _regexp = new RegExp(re);
    } else if (re is RegExp) {
      _regexp = re;
    } else {
      throw new ArgumentError('matches requires a regexp or string');
    }
  }

  bool matches(item, MatchState matchState) =>
    item is String ? _regexp.hasMatch(item) : false;

  Description describe(Description description) =>
      description.add("match '${_regexp.pattern}'");
}

// String matchers match against a string. We add this intermediate
// class to give better mismatch error messages than the base Matcher class.
abstract class _StringMatcher extends BaseMatcher {
  const _StringMatcher();
  Description describeMismatch(item, Description mismatchDescription,
                               MatchState matchState, bool verbose) {
    if (!(item is String)) {
      return mismatchDescription.
          addDescriptionOf(item).
          add(' not a string');
    } else {
      return super.describeMismatch(item, mismatchDescription,
          matchState, verbose);
    }
  }
}
