library typed_mock;


_InvocationMatcher _lastMatcher;

/// Enables stubbing methods.
///
/// Use it when you want the mock to return a particular value when a particular
/// method, getter or setter is called.
///
///     when(obj.testProperty).thenReturn(10);
///     expect(obj.testProperty, 10); // pass
///
/// You can specify multiple matchers, which are checked one after another.
///
///     when(obj.testMethod(anyInt)).thenReturn('was int');
///     when(obj.testMethod(anyString)).thenReturn('was String');
///     expect(obj.testMethod(42), 'was int'); // pass
///     expect(obj.testMethod('foo'), 'was String'); // pass
///
/// You can even provide a function to calculate results.
/// Function can be also used to capture invocation arguments (if you test some
/// consumer).
///
///     when(obj.testMethod(anyInt)).thenInvoke((int p) => 10 + p);
///     expect(obj.testMethod(1), 11); // pass
///     expect(obj.testMethod(5), 15); // pass
Behavior when(_ignored) {
  try {
    var mock = _lastMatcher._mock;
    mock._removeLastInvocation();
    // set behavior
    var behavior = new Behavior._(_lastMatcher);
    _lastMatcher._behavior = behavior;
    return behavior;
  } finally {
    // clear to prevent memory leak
    _lastMatcher = null;
  }
}


/// Clears all interactions remembered so far.
resetInteractions(TypedMock mock) {
  mock._invocations.clear();
  mock._verifiedInvocations.clear();
}


/// Verifies certain behavior happened a specified number of times.
Verifier verify(_ignored) {
  try {
    var mock = _lastMatcher._mock;
    mock._removeLastInvocation();
    // set verifier
    return new Verifier._(mock, _lastMatcher);
  } finally {
    // clear to prevent memory leak
    _lastMatcher = null;
  }
}


/// Verifies that the given mock doesn't have any unverified interaction.
void verifyNoMoreInteractions(TypedMock mock) {
  var notVerified = mock._computeNotVerifiedInvocations();
  // OK
  if (notVerified.isEmpty) {
    return;
  }
  // fail
  var invocationsString = _getInvocationsString(notVerified);
  throw new VerifyError('Unexpected interactions:\n$invocationsString');
}


/// Verifies that no interactions happened on the given mock.
void verifyZeroInteractions(TypedMock mock) {
  var invocations = mock._invocations;
  // OK
  if (invocations.isEmpty) {
    return;
  }
  // fail
  var invocationsString = _getInvocationsString(invocations);
  throw new VerifyError('Unexpected interactions:\n$invocationsString');
}


/// [VerifyError] is thrown when one of the [verify] checks fails.
class VerifyError {
  final String message;
  VerifyError(this.message);
  String toString() => 'VerifyError: $message';
}


String _getInvocationsString(Iterable<Invocation> invocations) {
  var buffer = new StringBuffer();
  invocations.forEach((invocation) {
    var member = invocation.memberName;
    buffer.write(member);
    buffer.write(' ');
    buffer.write(invocation.positionalArguments);
    buffer.write(' ');
    buffer.write(invocation.namedArguments);
    buffer.writeln();
  });
  return buffer.toString();
}


class _InvocationMatcher {
  final Symbol _member;
  final TypedMock _mock;
  final List<ArgumentMatcher> _matchers = [];

  Behavior _behavior;

  _InvocationMatcher(this._mock, this._member, Invocation invocation) {
    invocation.positionalArguments.forEach((argument) {
      ArgumentMatcher matcher;
      if (argument is ArgumentMatcher) {
        matcher = argument;
      } else {
        matcher = new _ArgumentMatcher_equals(argument);
      }
      _matchers.add(matcher);
    });
  }

  bool match(Invocation invocation) {
    var arguments = invocation.positionalArguments;
    if (arguments.length != _matchers.length) {
      return false;
    }
    for (int i = 0; i < _matchers.length; i++) {
      var matcher = _matchers[i];
      var argument = arguments[i];
      if (!matcher.matches(argument)) {
        return false;
      }
    }
    return true;
  }
}


class Behavior {
  final _InvocationMatcher _matcher;

  Behavior._(this._matcher);

  bool _thenFunctionEnabled = false;
  Function _thenFunction;

  bool _returnAlwaysEnabled = false;
  var _returnAlways;

  bool _returnListEnabled = false;
  List _returnList;
  int _returnListIndex;

  bool _throwExceptionEnabled = false;
  var _throwException;

  /// Invokes the given [function] with actual arguments and returns its result.
  Behavior thenInvoke(Function function) {
    _reset();
    _thenFunctionEnabled = true;
    _thenFunction = function;
    return this;
  }

  /// Returns the specific value.
  Behavior thenReturn(value) {
    _reset();
    _returnAlwaysEnabled = true;
    _returnAlways = value;
    return this;
  }

  /// Returns values from the [list] starting from first to the last.
  /// If the end of list is reached a [StateError] is thrown.
  Behavior thenReturnList(List list) {
    _reset();
    _returnListEnabled = true;
    _returnList = list;
    _returnListIndex = 0;
    return this;
  }

  /// Throws the specified [exception] object.
  Behavior thenThrow(exception) {
    _reset();
    _throwExceptionEnabled = true;
    _throwException = exception;
    return this;
  }

  _reset() {
    _thenFunctionEnabled = false;
    _returnAlwaysEnabled = false;
    _returnListEnabled = false;
    _throwExceptionEnabled = false;
  }

  dynamic _getReturnValue(Invocation invocation) {
    // function
    if (_thenFunctionEnabled) {
      return Function.apply(_thenFunction, invocation.positionalArguments,
          invocation.namedArguments);
    }
    // always
    if (_returnAlwaysEnabled) {
      return _returnAlways;
    }
    // list
    if (_returnListEnabled) {
      if (_returnListIndex >= _returnList.length) {
        throw new StateError('All ${_returnList.length} elements for '
            '${_matcher._member} from $_returnList have been exhausted.');
      }
      return _returnList[_returnListIndex++];
    }
    // exception
    if (_throwExceptionEnabled) {
      throw _throwException;
    }
    // no value
    return null;
  }
}


class Verifier {
  final TypedMock _mock;
  final _InvocationMatcher _matcher;

  Verifier._(this._mock, this._matcher);

  /// Marks matching interactions as verified and never fails.
  void any() {
    // mark as verified, but don't check the actual count
    _count();
  }

  /// Verifies that there was no matching interactions.
  void never() {
    times(0);
  }

  /// Verifies that there was excatly one martching interaction.
  void once() {
    times(1);
  }

  /// Verifies that there was the specified number of matching interactions.
  void times(int expected) {
    var times = _count();
    if (times != expected) {
      var member = _matcher._member;
      throw new VerifyError('$expected expected, but $times'
          ' invocations of $member recorded.');
    }
  }

  /// Verifies that there was at least the specified number of matching
  /// interactions.
  void atLeast(int expected) {
    var times = _count();
    if (times < expected) {
      var member = _matcher._member;
      throw new VerifyError('At least $expected expected, but only $times'
          ' invocations of $member recorded.');
    }
  }

  /// Verifies that there was at least one matching interaction.
  void atLeastOnce() {
    var times = _count();
    if (times == 0) {
      var member = _matcher._member;
      throw new VerifyError('At least one expected, but only zero'
          ' invocations of $member recorded.');
    }
  }

  /// Verifies that there was at most the specified number of matching
  /// interactions.
  void atMost(int expected) {
    var times = _count();
    if (times > expected) {
      var member = _matcher._member;
      throw new VerifyError('At most $expected expected, but $times'
          ' invocations of $member recorded.');
    }
  }

  int _count() {
    var times = 0;
    _mock._invocations.forEach((invocation) {
      if (invocation.memberName != _matcher._member) {
        return;
      }
      if (!_matcher.match(invocation)) {
        return;
      }
      _mock._verifiedInvocations.add(invocation);
      times++;
    });
    return times;
  }
}


/// A class to extend mocks from.
/// It supports specifying behavior using [when] and validation of interactions
/// using [verify].
///
///     abstract class Name {
///       String get firstName;
///       String get lastName;
///     }
///     class NameMock extends TypedMock implements Name {
///       noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
///     }
class TypedMock {
  final Map<Symbol, List<_InvocationMatcher>> _matchersMap = {};

  final List<Invocation> _invocations = [];
  final Set<Invocation> _verifiedInvocations = new Set<Invocation>();

  noSuchMethod(Invocation invocation) {
    _invocations.add(invocation);
    var member = invocation.memberName;
    // prepare invocation matchers
    var matchers = _matchersMap[member];
    if (matchers == null) {
      matchers = [];
      _matchersMap[member] = matchers;
    }
    // check if there is a matcher
    for (var matcher in matchers) {
      if (matcher.match(invocation)) {
        _lastMatcher = matcher;
        // generate value if there is a behavior
        if (matcher._behavior != null) {
          return matcher._behavior._getReturnValue(invocation);
        }
        // probably verification
        return null;
      }
    }
    // add a new matcher
    var matcher = new _InvocationMatcher(this, member, invocation);
    matchers.add(matcher);
    _lastMatcher = matcher;
  }

  Iterable<Invocation> _computeNotVerifiedInvocations() {
    notVerified(e) => !_verifiedInvocations.contains(e);
    return _invocations.where(notVerified);
  }

  void _removeLastInvocation() {
    _invocations.removeLast();
  }
}


/// [ArgumentMatcher] checks whether the given argument satisfies some
/// condition.
abstract class ArgumentMatcher {
  const ArgumentMatcher();

  /// Checks whether this matcher accepts the given argument.
  bool matches(val);
}


class _ArgumentMatcher_equals extends ArgumentMatcher {
  final expected;

  const _ArgumentMatcher_equals(this.expected);

  @override
  bool matches(val) {
    return val == expected;
  }
}


class _ArgumentMatcher_anyBool extends ArgumentMatcher {
  const _ArgumentMatcher_anyBool();

  @override
  bool matches(val) {
    return val is bool;
  }
}

/// Matches any [bool] value.
final anyBool = const _ArgumentMatcher_anyBool() as dynamic;


class _ArgumentMatcher_anyInt extends ArgumentMatcher {
  const _ArgumentMatcher_anyInt();

  @override
  bool matches(val) {
    return val is int;
  }
}

/// Matches any [int] value.
final anyInt = const _ArgumentMatcher_anyInt() as dynamic;


class _ArgumentMatcher_anyObject extends ArgumentMatcher {
  const _ArgumentMatcher_anyObject();

  @override
  bool matches(val) {
    return true;
  }
}

/// Matches any [Object] (or subclass) value.
final anyObject = const _ArgumentMatcher_anyObject() as dynamic;


class _ArgumentMatcher_anyString extends ArgumentMatcher {
  const _ArgumentMatcher_anyString();

  @override
  bool matches(val) {
    return val is String;
  }
}

/// Matches any [String] value.
final anyString = const _ArgumentMatcher_anyString() as dynamic;
