/*
 * Copyright 2016-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 -- Topology Region Module.
 Module that holds the current region in memory
 */

(function () {
    'use strict';

    // Injected Services
    var Model;

    // Internal
    var instance;

    // 'static' vars
    var ROOT = '(root)';

    angular.module('ovTopo2')
    .factory('Topo2RegionService', [
        '$log', 'Topo2Model', 'Topo2SubRegionService', 'Topo2DeviceService',
        'Topo2HostService', 'Topo2LinkService', 'Topo2ZoomService', 'Topo2DetailsPanelService',
        'Topo2BreadcrumbService', 'Topo2ViewController', 'Topo2SpriteLayerService', 'Topo2MapService',
        'Topo2MapConfigService', 'Topo2PeerRegionService', 'Topo2NoDevicesConnectedService',
        function ($log, _Model_, t2sr, t2ds, t2hs, t2ls, t2zs, t2dps, t2bcs, ViewController,
                  t2sls, t2ms, t2mcs, t2pr, t2ndcs) {

            Model = _Model_;

            var Region = ViewController.extend({
                initialize: function () {
                    instance = this;
                    this.model = null;

                    this.bgRendered = false;
                    this.regionData = null;
                    this.peers = null;

                    var RegionModel = Model.extend({
                        findNodeById: this.findNodeById,
                        nodes: this.regionNodes.bind(this)
                    });

                    this.model = new RegionModel();
                    this.createEmptyModel();

                },
                createEmptyModel: function () {
                    this.model.set({ subregions: t2sr.createSubRegionCollection([], this) });
                    this.model.set({ devices: t2ds.createDeviceCollection([], this) });
                    this.model.set({ hosts: t2hs.createHostCollection([], this) });
                    this.model.set({ peerRegions: t2pr.createCollection([], this) });
                    this.model.set({ links: t2ls.createLinkCollection([], this) });
                },
                isLoadComplete: function() {
                    return this.bgRendered && this.regionData && this.peers;
                },
                loaded: function (key, value) {
                    this[key] = value;
                    if (this.isLoadComplete()) {
                        this.startRegion();
                    }
                },
                startRegion: function () {

                    this.model.set({
                        id: this.regionData.id,
                        layerOrder: this.regionData.layerOrder
                    });

                    this.sortMultiLinks();

                    this.model.set({ subregions: t2sr.createSubRegionCollection(this.regionData.subregions, this) });
                    this.model.set({ devices: t2ds.createDeviceCollection(this.regionData.devices, this) });
                    this.model.set({ hosts: t2hs.createHostCollection(this.regionData.hosts, this) });
                    this.model.set({ peerRegions: t2pr.createCollection(this.peers, this) });
                    this.model.set({ links: t2ls.createLinkCollection(this.regionData.links, this) });

                    // Hide Breadcrumbs if there are no subregions configured in the root region
                    if (this.isRootRegion() && !this.model.get('subregions').models.length) {
                        t2bcs.hide();
                    }

                    this.layout.createForceLayout();
                    this.displayNoDevs();
                },
                clear: function () {
                    this.regionData = null;
                    this.createEmptyModel();
                },
                removePort: function (key) {
                    var regex = new RegExp('^[^/]*');
                    return regex.exec(key)[0];
                },
                sortMultiLinks: function () {
                    var _this = this,
                        deviceConnections = {};

                    _.each(this.regionData.links, function (link) {
                        var devA = _this.removePort(link.epA),
                            devB = _this.removePort(link.epB),
                            key = devA + '~' + devB;

                        if (!deviceConnections[key]) {
                            deviceConnections[key] = [];
                        }

                        deviceConnections[key].push(link);
                    });

                    _.each(deviceConnections, function (connection) {
                        if (connection.length > 1) {
                            _.orderBy(connection, ['portA']);
                            _.each(connection, function (link, index) {
                                link.multiline = {
                                    deviceLinks: connection.length,
                                    index: index
                                };
                            })
                        }
                    });
                },
                isRootRegion: function () {
                    return this.model.get('id') === ROOT;
                },
                findNodeById: function (link, id) {
                    if (link.get('type') !== 'UiEdgeLink') {
                        id = this.removePort(id);
                    }
                    return this.model.get('devices').get(id) ||
                        this.model.get('hosts').get(id) ||
                        this.model.get('subregions').get(id);
                },
                regionNodes: function () {
                    if (this.model) {
                        return [].concat(
                            this.model.get('devices').models,
                            this.model.get('hosts').models,
                            this.model.get('subregions').models,
                            this.model.get('peerRegions').models
                        );
                    }
                    return [];
                },
                regionLinks: function () {
                    return this.model.get('links').models;
                },
                getLink: function (linkId) {
                    return this.model.get('links').get(linkId);
                },
                getDevice: function (deviceId) {
                    return this.model.get('devices').get(deviceId);
                },
                filterRegionNodes: function (predicate) {
                    var nodes = this.regionNodes();
                    return _.filter(nodes, predicate);
                },
                deselectAllNodes: function () {
                    var selected = this.filterRegionNodes(function (node) {
                        return node.get('selected', true);
                    });

                    if (selected.length) {

                        selected.forEach(function (node) {
                            node.deselect();
                        });

                        t2dps().el.hide();
                        return true;
                    }

                    return false;
                },
                deselectLink: function () {
                    var selected = _.filter(this.regionLinks(), function (link) {
                        return link.get('selected', true);
                    });

                    if (selected.length) {

                        selected.forEach(function (link) {
                            link.deselect();
                        });

                        t2dps().el.hide();
                        return true;
                    }

                    return false;
                },
                toggleHosts: function () {
                    var state = this.lookupPrefState('hosts');
                    this.updatePrefState('hosts', !state);

                    _.each(this.model.get('hosts').models, function (host) {
                        host.setVisibility();
                    });

                    _.each(this.model.get('links').models, function (link) {
                        link.setVisibility();
                    });
                },
                update: function (event) {

                    if (!this.isLoadComplete()){
                        this.layout.createForceLayout();
                    }

                    if (this[event.type]) {
                        this[event.type](event);
                    } else {
                        $log.error("Unhanded topology update", event);
                    }

                    this.layout.update()
                    this.displayNoDevs();
                },
                displayNoDevs: function () {
                    if (this.regionNodes().length > 0) {
                        t2ndcs.hide();
                    } else {
                        t2ndcs.show();
                    }
                },

                // Topology update event handlers
                LINK_ADDED_OR_UPDATED: function (event) {

                    var regionLinks = this.model.get('links'),
                        device;

                    if (!regionLinks) {
                        this.model.set({ links: t2ls.createLinkCollection([], this) })
                    }

                    if (event.memo === 'added') {
                        var link = this.model.get('links').add(event.data);
                        link.createLink();
                        $log.debug('Added Link', link);
                    }
                },
                LINK_REMOVED: function (event) {
                    var link = this.getLink(event.subject);
                    link.remove();
                    this.model.get('links').remove(link);
                },
                DEVICE_ADDED_OR_UPDATED: function (event) {

                    var regionDevices = this.model.get('devices'),
                        device;

                    if (!regionDevices) {
                        this.model.set({ devices: t2ds.createDeviceCollection([], this) })
                    }

                    if (event.memo === 'added') {
                        device = this.model.get('devices').add(event.data);
                        $log.debug('Added device', device);
                    } else if (event.memo === 'updated') {
                        device = this.getDevice(event.subject);
                        device.set(event.data);
                    }
                },
                DEVICE_REMOVED: function (event) {
                    device.remove();
                },
                HOST_ADDED_OR_UPDATED: function (event) {
                    var regionHosts = this.model.get('hosts'),
                        host;

                    if (!regionHosts) {
                        this.model.set({ hosts: t2hs.createHostCollection([], this) })
                    }

                    if (event.memo === 'added') {
                        host = this.model.get('hosts').add(event.data);
                        $log.debug('Added host', host);
                    }
                },
                REGION_ADDED_OR_UPDATED: function (event) {
                    var regionSubRegions = this.model.get('subregions'),
                        region;

                    if (!regionSubRegions) {
                        this.model.set({ subregions: t2sr.createSubRegionCollection([], this) })
                    }

                    if (event.memo === 'added') {
                        region = this.model.get('subregions').add(event.data);
                        $log.debug('Added region', region);
                    }
                }
            });

            function getInstance() {
                return instance || new Region();
            }

            return getInstance();

        }]);

})();
