/*
 * 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.assignPeerLocations();

                    // TODO: RegionLinks are dublicated in JSON Payload

                    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];
                },
                assignPeerLocations: function () {
                    var _this = this;
                    _.each(this.regionData.peerLocations, function (location, id) {
                        _.each(_this.peers, function (peer) {
                            if (peer.id === id) {
                                peer.location = location;
                            }
                        })
                    });
                },
                sortMultiLinks: function () {
                    var _this = this,
                        deviceConnections = {};

                    _.each(this.regionData.links, function (link) {

                        var epA = _this.removePort(link.epA),
                            epB = _this.removePort(link.epB),
                            key = epA + '~' + epB,
                            collection = deviceConnections[key] || [],
                            dup = _.find(collection, link);

                        // 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 (!dup) {
                            collection.push(link);
                        }

                        deviceConnections[key] = collection;
                    });

                    _.forIn(deviceConnections, function (collection) {
                        if (collection.length > 1) {
                            _.each(collection, function (link, index) {
                                link.multiline = {
                                    deviceLinks: collection.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();

        }]);

})();
