// 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 unittest;

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);
    }
  }
}

