/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

describe('iOS exec', function () {
    var SERVICE = 'TestService';
    var ACTION = 'TestAction';
    var VC_ADDR = '1234';

    var cordova = require('cordova');
    var exec = require('cordova/iosexec');
    var mockxhr = require('cordova/mockxhr');
    var winSpy = jasmine.createSpy('win');
    var failSpy = jasmine.createSpy('fail');

    beforeEach(function() {
        winSpy.reset();
        failSpy.reset();
        mockxhr.install();
        exec.setJsToNativeBridgeMode(exec.jsToNativeModes.XHR_NO_PAYLOAD);
        navigator = { userAgent: 'hi there (' + VC_ADDR + ')' };
    });

    afterEach(function() {
        expect(mockxhr.activeXhrs.length).toBe(0);
        delete navigator;
    });

    afterEach(mockxhr.uninstall);

    function expectXhr() {
        expect(mockxhr.activeXhrs.length).toBeGreaterThan(0, 'expected an XHR to have been sent.');
        var mockXhr = mockxhr.activeXhrs[0];
        expect(mockXhr.url).toMatch(/^\/!gap_exec\\?/);
        expect(mockXhr.requestHeaders['vc']).toBe(VC_ADDR, 'missing vc header');
        expect(mockXhr.requestHeaders['rc']).toBeDefined('missing rc header.');
        expect(mockXhr.requestHeaders['cmds']).not.toBeDefined();
        expect(mockXhr.requestPayload).toBe(null);
        mockXhr.simulateResponse(200, '');
    }

    function simulateNativeBehaviour(codes) {
        var execPayload = JSON.parse(exec.nativeFetchMessages());
        while (execPayload.length && codes.length) {
            var curPayload = execPayload.shift();
            var callbackId = curPayload[0];
            var moreResults = exec.nativeCallback(callbackId, codes.shift(), 'payload', false);
            if (moreResults) {
                execPayload.push.apply(execPayload, JSON.parse(moreResults));
            }
        }
        expect(codes.length).toBe(0, 'Wrong number of results.');
    }

    describe('exec', function() {
        it('should return "" from nativeFetchMessages work when nothing is pending.', function() {
            var execPayload = exec.nativeFetchMessages();
            expect(execPayload).toBe('');
        });
        it('should work in the win case.', function() {
            exec(winSpy, failSpy, SERVICE, ACTION, []);
            expectXhr();
            simulateNativeBehaviour([1]);
            expect(winSpy).toHaveBeenCalledWith('payload');
            expect(failSpy).not.toHaveBeenCalled();
        });
        it('should work in the fail case.', function() {
            exec(winSpy, failSpy, SERVICE, ACTION, []);
            expectXhr();
            simulateNativeBehaviour([2]);
            expect(winSpy).not.toHaveBeenCalled();
            expect(failSpy).toHaveBeenCalledWith('payload');
        });
        it('should use only one XHR for multiple calls.', function() {
            exec(winSpy, failSpy, SERVICE, ACTION, []);
            exec(winSpy, failSpy, SERVICE, ACTION, []);
            expectXhr();
            simulateNativeBehaviour([1, 2]);
            expect(winSpy).toHaveBeenCalledWith('payload');
            expect(failSpy).toHaveBeenCalledWith('payload');
        });
        it('should send an extra XHR when commands flushed before XHR finishes', function() {
            exec(winSpy, failSpy, SERVICE, ACTION, []);
            simulateNativeBehaviour([1]);
            exec(winSpy, failSpy, SERVICE, ACTION, []);
            expectXhr();
            expectXhr();
            simulateNativeBehaviour([2]);
            expect(winSpy).toHaveBeenCalledWith('payload');
            expect(failSpy).toHaveBeenCalledWith('payload');
        });
        it('should return pending calls made from callbacks.', function() {
            function callMore() {
                exec(winSpy, failSpy, SERVICE, ACTION, []);
                exec(winSpy, failSpy, SERVICE, ACTION, []);
            }
            exec(callMore, failSpy, SERVICE, ACTION, []);
            expectXhr();
            simulateNativeBehaviour([1, 1, 1]);
            expect(winSpy.callCount).toBe(2);
            expect(failSpy).not.toHaveBeenCalled();
        });
    });
});
