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

/**
 * A directive for managing all active Guacamole sessions.
 */
angular.module('settings').directive('guacSettingsSessions', [function guacSettingsSessions() {
    
    return {
        // Element only
        restrict: 'E',
        replace: true,

        scope: {
        },

        templateUrl: 'app/settings/templates/settingsSessions.html',
        controller: ['$scope', '$injector', function settingsSessionsController($scope, $injector) {

            // Required types
            var ActiveConnectionWrapper = $injector.get('ActiveConnectionWrapper');
            var ConnectionGroup         = $injector.get('ConnectionGroup');
            var SortOrder               = $injector.get('SortOrder');

            // Required services
            var $filter                 = $injector.get('$filter');
            var $translate              = $injector.get('$translate');
            var $q                      = $injector.get('$q');
            var activeConnectionService = $injector.get('activeConnectionService');
            var authenticationService   = $injector.get('authenticationService');
            var connectionGroupService  = $injector.get('connectionGroupService');
            var dataSourceService       = $injector.get('dataSourceService');
            var guacNotification        = $injector.get('guacNotification');
            var requestService          = $injector.get('requestService');

            /**
             * The identifiers of all data sources accessible by the current
             * user.
             *
             * @type String[]
             */
            var dataSources = authenticationService.getAvailableDataSources();

            /**
             * The ActiveConnectionWrappers of all active sessions accessible
             * by the current user, or null if the active sessions have not yet
             * been loaded.
             *
             * @type ActiveConnectionWrapper[]
             */
            $scope.wrappers = null;

            /**
             * SortOrder instance which maintains the sort order of the visible
             * connection wrappers.
             *
             * @type SortOrder
             */
            $scope.wrapperOrder = new SortOrder([
                'activeConnection.username',
                'startDate',
                'activeConnection.remoteHost',
                'name'
            ]);

            /**
             * Array of all wrapper properties that are filterable.
             *
             * @type String[]
             */
            $scope.filteredWrapperProperties = [
                'activeConnection.username',
                'startDate',
                'activeConnection.remoteHost',
                'name'
            ];

            /**
             * All active connections, if known, grouped by corresponding data
             * source identifier, or null if active connections have not yet
             * been loaded.
             *
             * @type Object.<String, Object.<String, ActiveConnection>>
             */
            var allActiveConnections = null;

            /**
             * Map of all visible connections by data source identifier and
             * object identifier, or null if visible connections have not yet
             * been loaded.
             *
             * @type Object.<String, Object.<String, Connection>>
             */
            var allConnections = null;

            /**
             * The date format for use for session-related dates.
             *
             * @type String
             */
            var sessionDateFormat = null;

            /**
             * Map of all currently-selected active connection wrappers by
             * data source and identifier.
             * 
             * @type Object.<String, Object.<String, ActiveConnectionWrapper>>
             */
            var allSelectedWrappers = {};

            /**
             * Adds the given connection to the internal set of visible
             * connections.
             *
             * @param {String} dataSource
             *     The identifier of the data source associated with the given
             *     connection.
             *
             * @param {Connection} connection
             *     The connection to add to the internal set of visible
             *     connections.
             */
            var addConnection = function addConnection(dataSource, connection) {

                // Add given connection to set of visible connections
                allConnections[dataSource][connection.identifier] = connection;

            };

            /**
             * Adds all descendant connections of the given connection group to
             * the internal set of connections.
             * 
             * @param {String} dataSource
             *     The identifier of the data source associated with the given
             *     connection group.
             *
             * @param {ConnectionGroup} connectionGroup
             *     The connection group whose descendant connections should be
             *     added to the internal set of connections.
             */
            var addDescendantConnections = function addDescendantConnections(dataSource, connectionGroup) {

                // Add all child connections
                angular.forEach(connectionGroup.childConnections, function addConnectionForDataSource(connection) {
                    addConnection(dataSource, connection);
                });

                // Add all child connection groups
                angular.forEach(connectionGroup.childConnectionGroups, function addConnectionGroupForDataSource(connectionGroup) {
                    addDescendantConnections(dataSource, connectionGroup);
                });

            };

            /**
             * Wraps all loaded active connections, storing the resulting array
             * within the scope. If required data has not yet finished loading,
             * this function has no effect.
             */
            var wrapAllActiveConnections = function wrapAllActiveConnections() {

                // Abort if not all required data is available
                if (!allActiveConnections || !allConnections || !sessionDateFormat)
                    return;

                // Wrap all active connections for sake of display
                $scope.wrappers = [];
                angular.forEach(allActiveConnections, function wrapActiveConnections(activeConnections, dataSource) {
                    angular.forEach(activeConnections, function wrapActiveConnection(activeConnection, identifier) {

                        // Retrieve corresponding connection
                        var connection = allConnections[dataSource][activeConnection.connectionIdentifier];

                        // Add wrapper
                        if (activeConnection.username !== null) {
                            $scope.wrappers.push(new ActiveConnectionWrapper({
                                dataSource       : dataSource,
                                name             : connection.name,
                                startDate        : $filter('date')(activeConnection.startDate, sessionDateFormat),
                                activeConnection : activeConnection
                            }));
                        }

                    });
                });

            };

            // Retrieve all connections 
            dataSourceService.apply(
                connectionGroupService.getConnectionGroupTree,
                dataSources,
                ConnectionGroup.ROOT_IDENTIFIER
            )
            .then(function connectionGroupsReceived(rootGroups) {

                allConnections = {};

                // Load connections from each received root group
                angular.forEach(rootGroups, function connectionGroupReceived(rootGroup, dataSource) {
                    allConnections[dataSource] = {};
                    addDescendantConnections(dataSource, rootGroup);
                });

                // Attempt to produce wrapped list of active connections
                wrapAllActiveConnections();

            }, requestService.WARN);
            
            // Query active sessions
            dataSourceService.apply(
                activeConnectionService.getActiveConnections,
                dataSources
            )
            .then(function sessionsRetrieved(retrievedActiveConnections) {

                // Store received map of active connections
                allActiveConnections = retrievedActiveConnections;

                // Attempt to produce wrapped list of active connections
                wrapAllActiveConnections();

            }, requestService.WARN);

            // Get session date format
            $translate('SETTINGS_SESSIONS.FORMAT_STARTDATE').then(function sessionDateFormatReceived(retrievedSessionDateFormat) {

                // Store received date format
                sessionDateFormat = retrievedSessionDateFormat;

                // Attempt to produce wrapped list of active connections
                wrapAllActiveConnections();

            }, angular.noop);

            /**
             * Returns whether critical data has completed being loaded.
             *
             * @returns {Boolean}
             *     true if enough data has been loaded for the user interface
             *     to be useful, false otherwise.
             */
            $scope.isLoaded = function isLoaded() {
                return $scope.wrappers !== null;
            };

            /**
             * An action to be provided along with the object sent to
             * showStatus which closes the currently-shown status dialog.
             */
            var CANCEL_ACTION = {
                name        : "SETTINGS_SESSIONS.ACTION_CANCEL",
                // Handle action
                callback    : function cancelCallback() {
                    guacNotification.showStatus(false);
                }
            };
            
            /**
             * An action to be provided along with the object sent to
             * showStatus which immediately deletes the currently selected
             * sessions.
             */
            var DELETE_ACTION = {
                name        : "SETTINGS_SESSIONS.ACTION_DELETE",
                className   : "danger",
                // Handle action
                callback    : function deleteCallback() {
                    deleteAllSessionsImmediately();
                    guacNotification.showStatus(false);
                }
            };
            
            /**
             * Immediately deletes the selected sessions, without prompting the
             * user for confirmation.
             */
            var deleteAllSessionsImmediately = function deleteAllSessionsImmediately() {

                var deletionRequests = [];

                // Perform deletion for each relevant data source
                angular.forEach(allSelectedWrappers, function deleteSessionsImmediately(selectedWrappers, dataSource) {

                    // Delete sessions, if any are selected
                    var identifiers = Object.keys(selectedWrappers);
                    if (identifiers.length)
                        deletionRequests.push(activeConnectionService.deleteActiveConnections(dataSource, identifiers));

                });

                // Update interface
                $q.all(deletionRequests)
                .then(function activeConnectionsDeleted() {

                    // Remove deleted connections from wrapper array
                    $scope.wrappers = $scope.wrappers.filter(function activeConnectionStillExists(wrapper) {
                        return !(wrapper.activeConnection.identifier in (allSelectedWrappers[wrapper.dataSource] || {}));
                    });

                    // Clear selection
                    allSelectedWrappers = {};

                }, guacNotification.SHOW_REQUEST_ERROR);

            }; 
            
            /**
             * Delete all selected sessions, prompting the user first to
             * confirm that deletion is desired.
             */
            $scope.deleteSessions = function deleteSessions() {
                // Confirm deletion request
                guacNotification.showStatus({
                    'title'      : 'SETTINGS_SESSIONS.DIALOG_HEADER_CONFIRM_DELETE',
                    'text'       : {
                        'key' : 'SETTINGS_SESSIONS.TEXT_CONFIRM_DELETE'
                    },
                    'actions'    : [ DELETE_ACTION, CANCEL_ACTION]
                });
            };
            
            /**
             * Returns whether the selected sessions can be deleted.
             * 
             * @returns {Boolean}
             *     true if selected sessions can be deleted, false otherwise.
             */
            $scope.canDeleteSessions = function canDeleteSessions() {

                // We can delete sessions if at least one is selected
                for (var dataSource in allSelectedWrappers) {
                    for (var identifier in allSelectedWrappers[dataSource])
                        return true;
                }

                return false;

            };
            
            /**
             * Called whenever an active connection wrapper changes selected
             * status.
             * 
             * @param {ActiveConnectionWrapper} wrapper
             *     The wrapper whose selected status has changed.
             */
            $scope.wrapperSelectionChange = function wrapperSelectionChange(wrapper) {

                // Get selection map for associated data source, creating if necessary
                var selectedWrappers = allSelectedWrappers[wrapper.dataSource];
                if (!selectedWrappers)
                    selectedWrappers = allSelectedWrappers[wrapper.dataSource] = {};

                // Add wrapper to map if selected
                if (wrapper.checked)
                    selectedWrappers[wrapper.activeConnection.identifier] = wrapper;

                // Otherwise, remove wrapper from map
                else
                    delete selectedWrappers[wrapper.activeConnection.identifier];

            };
            
        }]
    };
    
}]);
