/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * Licensed 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.
 */

/*
 ONOS GUI -- Widget -- Table Service - Unit Tests
 */

// NOTE TableService does not exist! It has been replaced/renamed?

xdescribe('factory: fw/widget/table.js', function () {
    var $log, $compile, $rootScope,
        fs, ts, mast, is,
        scope,
        containerDiv,
        headerDiv, bodyDiv,
        header, body,
        mockHeader,
        mockHeaderHeight = 40;

    var onosFixedHeaderTags =
            '<div class="summary-list" onos-fixed-header>' +
            '<div class="table-header">' +
                '<table>' +
                    '<tr>' +
                        '<td colId="type" class="table-icon"></td>' +
                        '<td colId="id">Host ID </td>' +
                        '<td colId="mac" sortable>MAC Address </td>' +
                        '<td colId="location" col-width="110px">Location </td>' +
                    '</tr>' +
                '</table>' +
            '</div>' +

            '<div class="table-body">' +
                '<table>' +
                    '<tr class="ignore-width">' +
                        '<td class="not-picked"></td>' +
                    '</tr>' +
                    '<tr>' +
                        '<td class="table-icon">Some Icon</td>' +
                        '<td>Some ID</td>' +
                        '<td>Some MAC Address</td>' +
                        '<td>Some Location</td>' +
                    '</tr>' +
                '</table>' +
            '</div>' +
            '</div>',

        onosSortableHeaderTags =
            '<div onos-sortable-header ' +
            'sort-callback="sortCallback(requestParams)">' +
                '<table>' +
                    '<tr>' +
                        '<td colId="type"></td>' +
                        '<td colId="id" sortable>Host ID </td>' +
                        '<td colId="mac" sortable>MAC Address </td>' +
                        '<td colId="location" sortable>Location </td>' +
                    '</tr>' +
                '</table>' +
            '</div>';

    beforeEach(module('onosWidget', 'onosUtil', 'onosMast', 'onosSvg'));

    var mockWindow = {
        innerWidth: 600,
        innerHeight: 400,
        navigator: {
            userAgent: 'defaultUA'
        },
        on: function () {},
        addEventListener: function () {}
    };

    beforeEach(function () {
        module(function ($provide) {
            $provide.value('$window', mockWindow);
        });
    });

    beforeEach(inject(function (_$log_, _$compile_, _$rootScope_,
                                FnService, TableService, MastService, IconService) {
        $log = _$log_;
        $compile = _$compile_;
        $rootScope = _$rootScope_;
        fs = FnService;
        ts = TableService;
        mast = MastService;
        is = IconService;
    }));

    beforeEach(function () {
        scope = $rootScope.$new();
        scope.tableData = [];
    });

    // Note: dummy header so that d3 doesn't trip up.
    //       $compile has to be used on the directive tag element, so it can't
    //       be included in the tag strings declared above.
    beforeEach(function () {
        mockHeader = d3.select('body')
            .append('h2')
            .classed('tabular-header', true)
            .style({
                height: mockHeaderHeight + 'px',
                margin: 0,
                padding: 0
            })
            .text('Some Header');
    });

    afterEach(function () {
        containerDiv = undefined;
        headerDiv = undefined;
        bodyDiv = undefined;
        header = undefined;
        body = undefined;
        mockHeader.remove();
    });

    function populateTableData() {
        scope.tableData = [
            {
                type: 'endstation',
                id: '1234',
                mac: '00:00:03',
                location: 'USA'
            }
        ];
    }

    it('should define TableBuilderService', function () {
        expect(ts).toBeDefined();
    });

    it('should define api functions', function () {
        expect(fs.areFunctions(ts, [
            'resetSortIcons'
        ])).toBeTruthy();
    });

    function compile(elem) {
        var compiled = $compile(elem);
        compiled(scope);
        scope.$digest();
    }

    function selectTables() {
        expect(containerDiv.find('div').length).toBe(2);

        headerDiv = angular.element(containerDiv[0].querySelector('.table-header'));
        expect(headerDiv.length).toBe(1);

        bodyDiv = angular.element(containerDiv[0].querySelector('.table-body'));
        expect(bodyDiv.length).toBe(1);

        header = headerDiv.find('table');
        expect(header.length).toBe(1);

        body = bodyDiv.find('table');
        expect(body.length).toBe(1);
    }

    function verifyGivenTags(dirName, div) {
        expect(div).toBeDefined();
        expect(div.attr(dirName)).toBe('');
    }

    function verifyDefaultSize() {
        expect(header.css('width')).toBe('570px');
        expect(body.css('width')).toBe('570px');
    }

    function verifyHeight() {
        var padding = 22,
            mastHeight = 36,
            tableHeight = (mockWindow.innerHeight - mockHeaderHeight) -
                (fs.noPx(headerDiv.css('height')) + mastHeight + padding);

        expect(bodyDiv.css('height')).toBe(tableHeight + 'px');
    }

    function verifyColWidth() {
        var hdrs = header.find('td'),
            cols = body.find('td');

        expect(angular.element(hdrs[0]).css('width')).toBe('33px');
        expect(angular.element(hdrs[3]).css('width')).toBe('110px');

        expect(angular.element(cols[1]).css('width')).toBe('33px');
        expect(angular.element(cols[4]).css('width')).toBe('110px');
    }

    function verifyCallbacks(h) {
        expect(scope.sortCallback).not.toHaveBeenCalled();

        h[0].click();
        expect(scope.sortCallback).not.toHaveBeenCalled();

        h[1].click();
        expect(scope.sortCallback).toHaveBeenCalledWith({
            sortCol: 'id',
            sortDir: 'asc'
        });
        h[1].click();
        expect(scope.sortCallback).toHaveBeenCalledWith({
            sortCol: 'id',
            sortDir: 'desc'
        });
        h[1].click();
        expect(scope.sortCallback).toHaveBeenCalledWith({
            sortCol: 'id',
            sortDir: 'asc'
        });

        h[2].click();
        expect(scope.sortCallback).toHaveBeenCalledWith({
            sortCol: 'mac',
            sortDir: 'asc'
        });
        h[2].click();
        expect(scope.sortCallback).toHaveBeenCalledWith({
            sortCol: 'mac',
            sortDir: 'desc'
        });
        h[2].click();
        expect(scope.sortCallback).toHaveBeenCalledWith({
            sortCol: 'mac',
            sortDir: 'asc'
        });

        h[3].click();
        expect(scope.sortCallback).toHaveBeenCalledWith({
            sortCol: 'location',
            sortDir: 'asc'
        });
        h[3].click();
        expect(scope.sortCallback).toHaveBeenCalledWith({
            sortCol: 'location',
            sortDir: 'desc'
        });
        h[3].click();
        expect(scope.sortCallback).toHaveBeenCalledWith({
            sortCol: 'location',
            sortDir: 'asc'
        });
    }

    function verifyIcons(h) {
        var currH, div;

        h[1].click();
        currH = angular.element(h[1]);
        div = currH.find('div');
        expect(div.html()).toBe(
            '<svg class="embeddedIcon" width="10" height="10" viewBox="0 0 ' +
            '50 50"><g class="icon upArrow"><rect width="50" height="50" ' +
            'rx="5"></rect><use width="50" height="50" class="glyph" xmlns:' +
            'xlink="http://www.w3.org/1999/xlink" xlink:href="#triangleUp">' +
            '</use></g></svg>'
        );
        h[1].click();
        div = currH.find('div');
        expect(div.html()).toBe(
            '<svg class="embeddedIcon" width="10" height="10" viewBox="0 0 ' +
            '50 50"><g class="icon downArrow"><rect width="50" height="50" ' +
            'rx="5"></rect><use width="50" height="50" class="glyph" xmlns:' +
            'xlink="http://www.w3.org/1999/xlink" xlink:href="#triangleDown">' +
            '</use></g></svg>'
        );

        h[2].click();
        div = currH.children();
        // clicked on a new element, so the previous icon should have been deleted
        expect(div.html()).toBeFalsy();

        // the new element should have the ascending icon
        currH = angular.element(h[2]);
        div = currH.children();
        expect(div.html()).toBe(
            '<svg class="embeddedIcon" width="10" height="10" viewBox="0 0 ' +
            '50 50"><g class="icon upArrow"><rect width="50" height="50" ' +
            'rx="5"></rect><use width="50" height="50" class="glyph" xmlns:' +
            'xlink="http://www.w3.org/1999/xlink" xlink:href="#triangleUp">' +
            '</use></g></svg>'
        );
    }

    it('should affirm that onos-fixed-header is working', function () {
        containerDiv = angular.element(onosFixedHeaderTags);

        compile(containerDiv);

        verifyGivenTags('onos-fixed-header', containerDiv);
        selectTables();
        verifyDefaultSize();

        populateTableData();

        scope.$emit('LastElement');
        scope.$digest();

        verifyHeight();
        verifyColWidth();

        mockWindow.innerHeight = 300;
        scope.$digest();
        verifyHeight();

        mockWindow.innerWidth = 500;
        scope.$digest();
        verifyColWidth();
    });

    it('should affirm that onos-sortable-header is working', function () {
        headerDiv = angular.element(onosSortableHeaderTags);

        compile(headerDiv);
        verifyGivenTags('onos-sortable-header', headerDiv);

        scope.sortCallback = jasmine.createSpy('sortCallback');

        header = headerDiv.find('td');
        verifyCallbacks(header);
        verifyIcons(header);
    });

    // Note: testing resetSortIcons isn't feasible because due to the nature of
    //       directive compilation: they are jQuery elements, not d3 elements,
    //       so the function doesn't work.

});
