coreFramework.factory('RestangularInterceptor', ['Restangular', '$q', function (Restangular, $q) {
    var methodStash = {};
    var callCache = [];
    var methods = ['all', 'allUrl', 'one', 'oneUrl'];
    var subMethods = ['get', 'getList', 'put', 'post', 'remove', 'head', 'trace', 'options', 'patch'];

    function stashMethods() {
        for (var i in methods) {
            methodStash[methods[i]] = Restangular[methods[i]];
        }
    }

    function restoreMethods() {
        for (var i in methods) {
            Restangular[methods[i]] = methodStash[methods[i]];
        }
    }

    function mockMethods() {
        for (var m in methods) {
            Restangular[methods[m]] = (function(container) {
                return function () {
                    var containerParams = arguments;
                    var ret = {};

                    for (var s in subMethods) {
                        ret[subMethods[s]] = (function(method) {
                            return function () {
                                var methodParams = arguments;
                                var deferred = $q.defer();
                                callCache.push({ 'container': container, 'containerParams': containerParams, 'method': method, 'methodParams': methodParams, 'deferred': deferred });
                                return deferred.promise;
                            };
                        }(subMethods[s]));
                    }

                    return ret;
                };
            }(methods[m]));
        }
    }

    function executeCalls() {
        var fc;

        for (var i in callCache) {
            fc = callCache[i];
            (function(fc) {
                Restangular[fc.container].apply(Restangular, fc.containerParams)[fc.method].apply(Restangular, fc.methodParams).then(function (response) {
                    fc.deferred.resolve(response);
                });
            })(fc);
        }

        callCache = [];
    }

    return {
        hold: function () {
            stashMethods();
            mockMethods();
        },
        release: function () {
            restoreMethods();
            executeCalls();
        }
    };
}]);
