/*
 *
 * 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.
 *
*/

/* eslint-env jasmine */
/* global Connection */

exports.defineAutoTests = function () {
    describe('Network (navigator.connection)', function () {
        it('network.spec.1 should exist', function () {
            expect(navigator.connection).toBeDefined();
        });

        it('network.spec.2 should be set to a valid value', function () {
            var validValues = {
                unknown: 1,
                ethernet: 1,
                wifi: 1,
                '2g': 1,
                cellular: 1,
                '3g': 1,
                '4g': 1,
                none: 1
            };
            expect(validValues[navigator.connection.type]).toBe(1);
        });

        it('network.spec.4 should define constants for connection status', function () {
            expect(Connection.UNKNOWN).toBe('unknown');
            expect(Connection.ETHERNET).toBe('ethernet');
            expect(Connection.WIFI).toBe('wifi');
            expect(Connection.CELL_2G).toBe('2g');
            expect(Connection.CELL_3G).toBe('3g');
            expect(Connection.CELL_4G).toBe('4g');
            expect(Connection.NONE).toBe('none');
            expect(Connection.CELL).toBe('cellular');
        });
    });
};

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

exports.defineManualTests = function (contentEl, createActionButton) {
    function eventOutput (s) {
        var el = document.getElementById('results');
        el.innerHTML = el.innerHTML + s + '<br>';
    }

    function printNetwork () {
        eventOutput('navigator.connection.type=' + navigator.connection.type);
    }

    function onEvent (e) {
        eventOutput('Event of type: ' + e.type);
        printNetwork();
    }

    /******************************************************************************/

    var html = '<div id="info">' +
        '<b>Results:</b><br>' +
        '<span id="results"></span>' +
        '</div><div id="connection"></div>' +
        'Expected result: Status box will update with type of connection using two different methods. Both values must match.' +
        '  The result will be unknown, ethernet, wifi, 2g, 3g, 4g, none, or cellular. Make sure it matches what the device is connected to.' +
        '</p> <div id="actions"></div>';

    document.addEventListener('online', onEvent, false);
    document.addEventListener('offline', onEvent, false);
    contentEl.innerHTML = html;

    createActionButton('Show Network Connection', function () {
        printNetwork();
    }, 'connection');

    createActionButton('Clear Log', function () {
        document.getElementById('results').innerHTML = '';
    }, 'actions');
};
