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

/* global define, module, require, exports */

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery',
                'd3',
                'nf.ErrorHandler',
                'nf.Common',
                'nf.Dialog',
                'nf.Storage',
                'nf.Client',
                'nf.ProcessGroup',
                'nf.Shell',
                'nf.CanvasUtils'],
            function ($, d3, nfErrorHandler, nfCommon, nfDialog, nfStorage, nfClient, nfProcessGroup, nfShell, nfCanvasUtils) {
                return (nf.ProcessGroupConfiguration = factory($, d3, nfErrorHandler, nfCommon, nfDialog, nfStorage, nfClient, nfProcessGroup, nfShell, nfCanvasUtils));
            });
    } else if (typeof exports === 'object' && typeof module === 'object') {
        module.exports = (nf.ProcessGroupConfiguration =
            factory(require('jquery'),
                require('d3'),
                require('nf.ErrorHandler'),
                require('nf.Common'),
                require('nf.Dialog'),
                require('nf.Storage'),
                require('nf.Client'),
                require('nf.ProcessGroup'),
                require('nf.Shell'),
                require('nf.CanvasUtils')));
    } else {
        nf.ProcessGroupConfiguration = factory(root.$,
            root.d3,
            root.nf.ErrorHandler,
            root.nf.Common,
            root.nf.Dialog,
            root.nf.Storage,
            root.nf.Client,
            root.nf.ProcessGroup,
            root.nf.Shell,
            root.nf.CanvasUtils);
    }
}(this, function ($, d3, nfErrorHandler, nfCommon, nfDialog, nfStorage, nfClient, nfProcessGroup, nfShell, nfCanvasUtils) {
    'use strict';

    var nfControllerServices;
    var nfParameterContexts;
    var nfBackpressureDefaults;

    var config = {
        urls: {
            api: '../nifi-api',
            parameterContexts: '../nifi-api/flow/parameter-contexts'
        }
    };

    /**
     * Initializes the general tab.
     */
    var initGeneral = function () {
    };

    /**
     * Gets the controller services table.
     *
     * @returns {*|jQuery|HTMLElement}
     */
    var getControllerServicesTable = function () {
        return $('#process-group-controller-services-table');
    };

    /**
     * Saves the configuration for the specified group.
     *
     * @param version
     * @param groupId
     */
    var saveConfiguration = function (version, groupId) {
        // build the entity
        var entity = {
            'revision': nfClient.getRevision({
                'revision': {
                    'version': version
                }
            }),
            'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged(),
            'component': {
                'id': groupId,
                'name': $('#process-group-name').val(),
                'comments': $('#process-group-comments').val(),
                'parameterContext': {
                    'id': $('#process-group-parameter-context-combo').combo('getSelectedOption').value
                },
                'flowfileConcurrency': $('#process-group-flowfile-concurrency-combo').combo('getSelectedOption').value,
                'flowfileOutboundPolicy': $('#process-group-outbound-policy-combo').combo('getSelectedOption').value,
                'defaultFlowFileExpiration': $('#process-group-default-flowfile-expiration').val(),
                'defaultBackPressureObjectThreshold': $('#process-group-default-back-pressure-object-threshold').val(),
                'defaultBackPressureDataSizeThreshold': $('#process-group-default-back-pressure-data-size-threshold').val()
            }
        };

        // update the selected component
        $.ajax({
            type: 'PUT',
            data: JSON.stringify(entity),
            url: config.urls.api + '/process-groups/' + encodeURIComponent(groupId),
            dataType: 'json',
            contentType: 'application/json'
        }).done(function (response) {
            // refresh the process group if necessary
            if (response.permissions.canRead && response.component.parentGroupId === nfCanvasUtils.getGroupId()) {
                nfProcessGroup.set(response);
            }

            // show the result dialog
            nfDialog.showOkDialog({
                headerText: 'Process Group Configuration',
                dialogContent: 'Process group configuration successfully saved.'
            });

            // update the click listener for the updated revision
            $('#process-group-configuration-save').off('click').on('click', function () {
                saveConfiguration(response.revision.version, groupId);
            });

            var controllerServicesUri = config.urls.api + '/flow/process-groups/' + encodeURIComponent(groupId) + '/controller-services';

            $.ajax({
                type: 'GET',
                url: controllerServicesUri,
                dataType: 'json'
            }).done(function (response) {
                var serviceTable = getControllerServicesTable();

                nfCommon.cleanUpTooltips(serviceTable, 'div.has-errors');

                var controllerServicesGrid = serviceTable.data('gridInstance');
                var controllerServicesData = controllerServicesGrid.getData();

                $.each(response.controllerServices, function (_, controllerServiceEntity) {
                    controllerServicesData.updateItem(controllerServiceEntity.id, controllerServiceEntity);
                });
            });

            nfCanvasUtils.reload();
        }).fail(nfErrorHandler.handleConfigurationUpdateAjaxError);
    };

    /**
     * Loads the configuration for the specified process group.
     *
     * @param {string} groupId
     */
    var loadConfiguration = function (groupId) {
        var setUnauthorizedText = function () {
            $('#read-only-process-group-name').text('Unauthorized');
            $('#read-only-process-group-comments').text('Unauthorized');
            $('#read-only-process-group-default-flowfile-expiration').text('Unauthorized');
            $('#read-only-process-group-default-back-pressure-object-threshold').text('Unauthorized');
            $('#read-only-process-group-default-back-pressure-data-size-threshold').text('Unauthorized');
        };

        var setEditable = function (editable) {
            if (editable) {
                $('#process-group-configuration div.editable').show();
                $('#process-group-configuration div.read-only').hide();
                $('#process-group-configuration-save').show();
            } else {
                $('#process-group-configuration div.editable').hide();
                $('#process-group-configuration div.read-only').show();
                $('#process-group-configuration-save').hide();
            }
        };

        // record the group id
        $('#process-group-id').text(groupId);

        // update the click listener
        $('#process-group-configuration-refresh-button').off('click').on('click', function () {
            loadConfiguration(groupId);
        });

        // update the new controller service click listener
        $('#add-process-group-configuration-controller-service').off('click').on('click', function () {
            var selectedTab = $('#process-group-configuration-tabs li.selected-tab').text();
            if (selectedTab === 'Controller Services') {
                var controllerServicesUri = config.urls.api + '/process-groups/' + encodeURIComponent(groupId) + '/controller-services';
                nfControllerServices.promptNewControllerService(controllerServicesUri, getControllerServicesTable());
            }
        });

        var processGroup = $.Deferred(function (deferred) {
            $.ajax({
                type: 'GET',
                url: config.urls.api + '/process-groups/' + encodeURIComponent(groupId),
                dataType: 'json'
            }).done(function (response) {
                // store the process group
                $('#process-group-configuration').data('process-group', response);

                var processGroup = response.component;

                if (response.permissions.canWrite) {

                    // populate the process group settings
                    $('#process-group-name').removeClass('unset').val(processGroup.name);
                    $('#process-group-comments').removeClass('unset').val(processGroup.comments);
                    $('#process-group-flowfile-concurrency-combo').removeClass('unset').combo({
                        options: [{
                                text: 'Single FlowFile Per Node',
                                value: 'SINGLE_FLOWFILE_PER_NODE',
                                description: 'Only a single FlowFile is to be allowed to enter the Process Group at a time on each node in the cluster. While that FlowFile may be split into many or '
                                    + 'spawn many children, no additional FlowFiles will be allowed to enter the Process Group through a Local Input Port until the previous FlowFile '
                                    + '- and all of its child/descendent FlowFiles - have been processed.'
                            }, {
                                text: 'Single Batch Per Node',
                                value: "SINGLE_BATCH_PER_NODE",
                                description: 'When an Input Port pulls a FlowFile into the Process Group, FlowFiles will continue to be ingested into the Process Group until all input queues '
                                    + 'have been emptied. At that point, no additional FlowFiles will be allowed to enter the Process Group through a Local Input Port until the entire batch '
                                    + 'of FlowFiles has been processed.'
                            },{
                                text: 'Unbounded',
                                value: 'UNBOUNDED',
                                description: 'The number of FlowFiles that can be processed concurrently is unbounded.'
                            }],
                        selectedOption: {
                            value: processGroup.flowfileConcurrency
                        }
                    });

                    $('#process-group-outbound-policy-combo').removeClass('unset').combo({
                        options: [{
                                text: 'Stream When Available',
                                value: 'STREAM_WHEN_AVAILABLE',
                                description: 'FlowFiles that are queued up to be transferred out of a Process Group by an Output Port will be transferred out '
                                        + 'of the Process Group as soon as they are available.'
                            }, {
                                text: 'Batch Output',
                                value: 'BATCH_OUTPUT',
                                description: 'FlowFiles that are queued up to be transferred out of a Process Group by an Output Port will remain queued until '
                                        + 'all FlowFiles in the Process Group are ready to be transferred out of the group. The FlowFiles will then be transferred '
                                        + 'out of the group. This setting will be ignored if the FlowFile Concurrency is Unbounded.'
                            }],
                        selectedOption: {
                            value: processGroup.flowfileOutboundPolicy
                        }
                    });

                    $('#process-group-default-flowfile-expiration').removeClass('unset').val(processGroup.defaultFlowFileExpiration);
                    $('#process-group-default-back-pressure-object-threshold').removeClass('unset').val(processGroup.defaultBackPressureObjectThreshold);
                    $('#process-group-default-back-pressure-data-size-threshold').removeClass('unset').val(processGroup.defaultBackPressureDataSizeThreshold);


                    // populate the header
                    $('#process-group-configuration-header-text').text(processGroup.name + ' Configuration');

                    setEditable(true);

                    // register the click listener for the save button
                    $('#process-group-configuration-save').off('click').on('click', function () {
                        saveConfiguration(response.revision.version, response.id);
                    });
                } else {
                    if (response.permissions.canRead) {
                        // populate the process group settings
                        $('#read-only-process-group-name').text(processGroup.name);
                        $('#read-only-process-group-comments').text(processGroup.comments);

                        // Determine the user-friendly name for the selected FlowFile Concurrency
                        var concurrencyName;
                        if (processGroup.flowfileConcurrency == "UNBOUNDED") {
                            concurrencyName = "Unbounded";
                        } else if (processGroup.flowfileConcurrency == "SINGLE_FLOWFILE_PER_NODE") {
                            concurrencyName = "Single FlowFile Per Node";
                        } else if (processGroup.flowfileConcurrency == "SINGLE_BATCH_PER_NODE") {
                            concurrencyName = "Single Batch Per Node";
                        } else {
                            concurrencyName = "Unknown";
                        }

                        $('#read-only-process-group-flowfile-concurrency').text(concurrencyName);

                        var outboundPolicyName = processGroup.flowfileOutboundPolicy == "BATCH_OUTPUT" ? "Batch Output" : "Stream When Available";
                        $('#read-only-process-group-outbound-policy').text(outboundPolicyName);

                        // populate the header
                        $('#process-group-configuration-header-text').text(processGroup.name + ' Configuration');

                        // backpressure settings
                        $('#process-group-default-flowfile-expiration').text(processGroup.defaultFlowFileExpiration);
                        $('#process-group-default-back-pressure-object-threshold').text(processGroup.defaultBackPressureObjectThreshold);
                        $('#process-group-default-back-pressure-data-size-threshold').text(processGroup.defaultBackPressureDataSizeThreshold);

                        $('#read-only-process-group-default-flowfile-expiration').text(processGroup.defaultFlowFileExpiration);
                        $('#read-only-process-group-default-back-pressure-object-threshold').text(processGroup.defaultBackPressureObjectThreshold);
                        $('#read-only-process-group-default-back-pressure-data-size-threshold').text(processGroup.defaultBackPressureDataSizeThreshold);
                    } else {
                        setUnauthorizedText();
                    }

                    setEditable(false);
                }
                deferred.resolve(response);
            }).fail(function (xhr, status, error) {
                if (xhr.status === 403) {
                    var unauthorizedGroup;
                    if (groupId === nfCanvasUtils.getGroupId()) {
                        unauthorizedGroup = {
                            'permissions': {
                                canRead: false,
                                canWrite: nfCanvasUtils.canWriteCurrentGroup()
                            }
                        };
                    } else {
                        unauthorizedGroup = nfProcessGroup.get(groupId);
                    }
                    $('#process-group-configuration').data('process-group', unauthorizedGroup);

                    setUnauthorizedText();
                    setEditable(false);
                    deferred.resolve(unauthorizedGroup);
                } else {
                    deferred.reject(xhr, status, error);
                }
            });
        }).promise();

        // load the controller services
        var controllerServicesUri = config.urls.api + '/flow/process-groups/' + encodeURIComponent(groupId) + '/controller-services';
        var controllerServices = nfControllerServices.loadControllerServices(controllerServicesUri, getControllerServicesTable());

        var parameterContexts = $.ajax({
                type: 'GET',
                url: config.urls.parameterContexts,
                dataType: 'json'
            });

        // wait for everything to complete
        return $.when(processGroup, controllerServices, parameterContexts).done(function (processGroupResult, controllerServicesResult, parameterContextsResult) {
            var controllerServicesResponse = controllerServicesResult[0];
            var parameterContextsResponse = parameterContextsResult[0];

            // update the current time
            $('#process-group-configuration-last-refreshed').text(controllerServicesResponse.currentTime);

            var parameterContexts = parameterContextsResponse.parameterContexts;
            var options = [{
                text: 'No parameter context',
                value: null
            }];

            var authorizedParameterContexts = parameterContexts.filter(function (parameterContext) {
                return parameterContext.permissions.canRead;
            });

            var unauthorizedParameterContexts = parameterContexts.filter(function (parameterContext) {
                return !parameterContext.permissions.canRead;
            });

            //sort alphabetically
            var sortedAuthorizedParameterContexts = authorizedParameterContexts.sort(function (a, b) {
                if (a.component.name < b.component.name) {
                    return -1;
                }
                if (a.component.name > b.component.name) {
                    return 1;
                }
                return 0;
            });

            //sort alphabetically
            var sortedUnauthorizedParameterContexts = unauthorizedParameterContexts.sort(function (a, b) {
                if (a.id < b.id) {
                    return -1;
                }
                if (a.id > b.id) {
                    return 1;
                }
                return 0;
            });

            var sortedParameterContexts = sortedAuthorizedParameterContexts.concat(sortedUnauthorizedParameterContexts);

            sortedParameterContexts.forEach(function (parameterContext) {
                var option;
                if (parameterContext.permissions.canRead) {
                    option = {
                        'text': parameterContext.component.name,
                        'value': parameterContext.id,
                        'description': parameterContext.component.description
                    };
                } else {
                    option = {
                        'disabled': true,
                        'text': parameterContext.id,
                        'value': parameterContext.id
                    }
                }

                options.push(option);
            });

            var createNewParameterContextOption = {
                text: 'Create new parameter context...',
                value: undefined,
                optionClass: 'unset'
            };

            if (nfCommon.canModifyParameterContexts()) {
                options.push(createNewParameterContextOption);
            }

            var comboOptions = {
                options: options,
                select: function (option) {
                    var combo = this;
                    if (typeof option.value === 'undefined') {
                        $('#parameter-context-dialog').modal('setHeaderText', 'Add Parameter Context').modal('setButtonModel', [{
                            buttonText: 'Apply',
                            color: {
                                base: '#728E9B',
                                hover: '#004849',
                                text: '#ffffff'
                            },
                            disabled: function () {
                                if ($('#parameter-context-name').val() !== '') {
                                    return false;
                                }
                                return true;
                            },
                            handler: {
                                click: function () {
                                    nfParameterContexts.addParameterContext(function (parameterContextEntity) {
                                        options.pop();
                                        var option = {
                                            'text': parameterContextEntity.component.name,
                                            'value': parameterContextEntity.component.id,
                                            'description': parameterContextEntity.component.description
                                        };
                                        options.push(option);

                                        if (nfCommon.canModifyParameterContexts()) {
                                            options.push(createNewParameterContextOption);
                                        }

                                        comboOptions.selectedOption = {
                                            value: parameterContextEntity.component.id
                                        };

                                        combo.combo('destroy').combo(comboOptions);
                                    });
                                }
                            }
                        }, {
                            buttonText: 'Cancel',
                            color: {
                                base: '#E3E8EB',
                                hover: '#C7D2D7',
                                text: '#004849'
                            },
                            handler: {
                                click: function () {
                                    $(this).modal('hide');
                                }
                            }
                        }]).modal('show');

                        // make sure the edit mode is properly set
                        if ($('#parameter-context-dialog').hasClass('read-only')) {
                            $('#parameter-context-dialog').removeClass('read-only');
                            $('#parameter-context-dialog').addClass('edit-mode');
                        }

                        // there is no id yet, make sure the id field isn't shown
                        if (!$('#parameter-context-id-setting').hasClass('hidden')) {
                            $('#parameter-context-id-setting').addClass('hidden');
                        }

                        // set the initial focus
                        $('#parameter-context-name').focus();
                    }
                }
            };

            // populate the parameter context
            if (nfCommon.isDefinedAndNotNull(processGroupResult.parameterContext)) {
                comboOptions.selectedOption = {
                    value: processGroupResult.parameterContext.id
                };
            }

            // initialize the parameter context combo
            $('#process-group-parameter-context-combo').combo('destroy').combo(comboOptions);
        }).fail(nfErrorHandler.handleAjaxError);
    };

    /**
     * Shows the process group configuration.
     */
    var showConfiguration = function () {
        // show the configuration dialog
        nfShell.showContent('#process-group-configuration').done(function () {
            reset();
        });

        //reset content to account for possible policy changes
        $('#process-group-configuration-tabs').find('.selected-tab').click();

        // adjust the table size
        nfProcessGroupConfiguration.resetTableSize();
    };

    /**
     * Resets the process group configuration dialog.
     */
    var reset = function () {
        $('#process-group-configuration').removeData('process-group');

        // reset button state
        $('#process-group-configuration-save').mouseout();

        // reset the fields
        $('#process-group-id').text('');
        $('#process-group-name').val('');
        $('#process-group-comments').val('');
        $('#process-group-default-flowfile-expiration').val('');
        $('#process-group-default-back-pressure-object-threshold').val('');
        $('#process-group-default-back-pressure-data-size-threshold').val('');

        // reset the header
        $('#process-group-configuration-header-text').text('Process Group Configuration');
    };

    var nfProcessGroupConfiguration = {

        /**
         * Initialize the process group configuration.
         *
         * @param nfControllerServicesRef   The nfControllerServices module.
         * @param nfParameterContextsRef    The nfParameterContexts module.
         */
        init: function (nfControllerServicesRef, nfParameterContextsRef) {
            nfControllerServices = nfControllerServicesRef;
            nfParameterContexts = nfParameterContextsRef;

            // initialize the process group configuration tabs
            $('#process-group-configuration-tabs').tabbs({
                tabStyle: 'tab',
                selectedTabStyle: 'selected-tab',
                scrollableTabContentStyle: 'scrollable',
                tabs: [{
                    name: 'General',
                    tabContentId: 'general-process-group-configuration-tab-content'
                }, {
                    name: 'Controller Services',
                    tabContentId: 'process-group-controller-services-tab-content'
                }],
                select: function () {
                    var processGroup = $('#process-group-configuration').data('process-group');
                    var canWrite = nfCommon.isDefinedAndNotNull(processGroup) ? processGroup.permissions.canWrite : false;

                    var tab = $(this).text();
                    if (tab === 'General') {
                        $('#flow-cs-availability').hide();
                        $('#add-process-group-configuration-controller-service').hide();

                        if (canWrite) {
                            $('#process-group-configuration-save').show();
                        } else {
                            $('#process-group-configuration-save').hide();
                        }
                    } else {
                        $('#flow-cs-availability').show();
                        $('#process-group-configuration-save').hide();

                        if (canWrite) {
                            $('#add-process-group-configuration-controller-service').show();
                            $('#process-group-controller-services-tab-content').css('top', '32px');
                        } else {
                            $('#add-process-group-configuration-controller-service').hide();
                            $('#process-group-controller-services-tab-content').css('top', '0');
                        }

                        // resize the table
                        nfProcessGroupConfiguration.resetTableSize();
                    }
                }
            });

            // initialize each tab
            initGeneral();
            nfControllerServices.init(getControllerServicesTable());
        },

        /**
         * Update the size of the grid based on its container's current size.
         */
        resetTableSize: function () {
            nfControllerServices.resetTableSize(getControllerServicesTable());
        },

        /**
         * Shows the settings dialog.
         */
        showConfiguration: function (groupId) {
            return loadConfiguration(groupId).done(showConfiguration);
        },

        /**
         * Loads the configuration for the specified process group.
         *
         * @param groupId
         */
        loadConfiguration: function (groupId) {
            return loadConfiguration(groupId);
        },

        /**
         * Selects the specified controller service.
         *
         * @param {string} controllerServiceId
         */
        selectControllerService: function (controllerServiceId) {
            var controllerServiceGrid = getControllerServicesTable().data('gridInstance');
            var controllerServiceData = controllerServiceGrid.getData();

            // select the desired service
            var row = controllerServiceData.getRowById(controllerServiceId);
            controllerServiceGrid.setSelectedRows([row]);
            controllerServiceGrid.scrollRowIntoView(row);

            // select the controller services tab
            $('#process-group-configuration-tabs').find('li:eq(1)').click();
        }
    };

    return nfProcessGroupConfiguration;
}));
