/*
 * 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] = [];
                        }

                        // TODO: Investigate why region contains dup links?!?!
                        // FIXME: This shouldn't be needed - The backend is sending dups
                        //        and this is preventing the client thinking its a multilink
                        if (deviceConnections[key].indexOf(link) > -1) {
                            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();
                    });

                    return !state;
                },
                toggleOfflineDevices: function () {
                    var state = this.lookupPrefState('offline_devices');
                    this.updatePrefState('offline_devices', !state);
                    _.each(this.regionNodes(), function (node) {
                        node.setOfflineVisibility();
                    });

                    return !state;
                },
                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();

        }]);

})();
