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;
