// 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 which matches if the match argument is greater
 * than the given [value].
 */

part of matcher;

Matcher greaterThan(value) =>
  new _OrderingComparison(value, false, false, true, 'a value greater than');

/**
 * Returns a matcher which matches if the match argument is greater
 * than or equal to the given [value].
 */
Matcher greaterThanOrEqualTo(value) =>
  new _OrderingComparison(value, true, false, true,
      'a value greater than or equal to');

/**
 * Returns a matcher which matches if the match argument is less
 * than the given [value].
 */
Matcher lessThan(value) =>
  new _OrderingComparison(value, false, true, false, 'a value less than');

/**
 * Returns a matcher which matches if the match argument is less
 * than or equal to the given [value].
 */
Matcher lessThanOrEqualTo(value) =>
  new _OrderingComparison(value, true, true, false,
      'a value less than or equal to');

/**
 * A matcher which matches if the match argument is zero.
 */
const Matcher isZero =
  const _OrderingComparison(0, true, false, false, 'a value equal to');


/**
 * A matcher which matches if the match argument is non-zero.
 */
const Matcher isNonZero =
  const _OrderingComparison(0, false, true, true, 'a value not equal to');

/**
 * A matcher which matches if the match argument is positive.
 */
const Matcher isPositive =
  const _OrderingComparison(0, false, false, true, 'a positive value', false);

/**
 * A matcher which matches if the match argument is zero or negative.
 */
const Matcher isNonPositive =
  const _OrderingComparison(0, true, true, false,
      'a non-positive value', false);

/**
 * A matcher which matches if the match argument is negative.
 */
const Matcher isNegative =
  const _OrderingComparison(0, false, true, false, 'a negative value', false);

/**
 * A matcher which matches if the match argument is zero or positive.
 */
const Matcher isNonNegative =
  const _OrderingComparison(0, true, false, true,
      'a non-negative value', false);

bool _isNumeric(value) {
  return value is int || value is double;
}

class _OrderingComparison extends BaseMatcher {
  /** Expected value. */
  final _value;
  /** What to return if actual == expected */
  final bool _equalValue;
  /** What to return if actual < expected */
  final bool _lessThanValue;
  /** What to return if actual > expected */
  final bool _greaterThanValue;
  /** Textual name of the inequality */
  final String _comparisonDescription;
  /** Whether to include the expected value in the description */
  final bool _valueInDescription;

  const _OrderingComparison(
    this._value,
    this._equalValue,
    this._lessThanValue,
    this._greaterThanValue,
    this._comparisonDescription,
    [valueInDescription = true]) :
      this._valueInDescription = valueInDescription;

  bool matches(item, MatchState matchState) {
    if (item == _value) {
      return _equalValue;
    } else if (item < _value) {
      return _lessThanValue;
    } else {
      return _greaterThanValue;
    }
  }

  Description describe(Description description) {
    if (_valueInDescription) {
      return description.add(_comparisonDescription).add(' ').
          addDescriptionOf(_value);
    } else {
      return description.add(_comparisonDescription);
    }
  }
}

/**
 * Returns a matcher which matches if the match argument is within [delta]
 * of some [value]; i.e. if the match argument is greater than
 * than or equal [value]-[delta] and less than or equal to [value]+[delta].
 */
Matcher closeTo(value, delta) => new _IsCloseTo(value, delta);

class _IsCloseTo extends BaseMatcher {
  final num _value, _delta;

  const _IsCloseTo(this._value, this._delta);

  bool matches(item, MatchState matchState) {
    if (!_isNumeric(item)) {
      return false;
    }
    var diff = item - _value;
    if (diff < 0) diff = -diff;
    return (diff <= _delta);
  }

  Description describe(Description description) =>
    description.add('a numeric value within ').
        addDescriptionOf(_delta).
        add(' of ').
        addDescriptionOf(_value);

  Description describeMismatch(item, Description mismatchDescription,
                               MatchState matchState, bool verbose) {
    if (item is !num) {
      return mismatchDescription.
          addDescriptionOf(item).
          add(' not numeric');
    } else {
      var diff = item - _value;
      if (diff < 0) diff = -diff;
      return mismatchDescription.
          addDescriptionOf(item).
          add(' differed by ').
          addDescriptionOf(diff);
    }
  }
}

/**
 * Returns a matcher which matches if the match argument is greater
 * than or equal to [low] and less than or equal to [high].
 */
Matcher inInclusiveRange(low, high) => new _InRange(low, high, true, true);

/**
 * Returns a matcher which matches if the match argument is greater
 * than [low] and less than [high].
 */
Matcher inExclusiveRange(low, high) => new _InRange(low, high, false, false);

/**
 * Returns a matcher which matches if the match argument is greater
 * than [low] and less than or equal to [high].
 */
Matcher inOpenClosedRange(low, high) => new _InRange(low, high, false, true);

/**
 * Returns a matcher which matches if the match argument is greater
 * than or equal to a [low] and less than [high].
 */
Matcher inClosedOpenRange(low, high) => new _InRange(low, high, true, false);

class _InRange extends BaseMatcher {
  final num _low, _high;
  final bool _lowMatchValue, _highMatchValue;

  const _InRange(this._low, this._high,
    this._lowMatchValue, this._highMatchValue);

  bool matches(value, MatchState matchState) {
    if (value is !num) {
      return false;
    }
    if (value < _low || value > _high) {
      return false;
    }
    if (value == _low) {
      return _lowMatchValue;
    }
    if (value == _high) {
      return _highMatchValue;
    }
    return true;
  }

  Description describe(Description description) =>
      description.add("be in range from "
        "$_low (${_lowMatchValue ? 'inclusive' : 'exclusive'}) to "
        "$_high (${_highMatchValue ? 'inclusive' : 'exclusive'})");

  Description describeMismatch(item, Description mismatchDescription,
                               MatchState matchState, bool verbose) {
    if (item is !num) {
      return mismatchDescription.
          addDescriptionOf(item).
          add(' not numeric');
    } else {
      return super.describeMismatch(item, mismatchDescription,
          matchState, verbose);
    }
  }
}

