/*-
 * ~~~~~~licensing~~~~~~
 * entaxy-management-plugin
 * ==========
 * Copyright (C) 2020 - 2023 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
var Entaxy;
(function (Entaxy) {
    Entaxy._module
    .component('entaxyTable', {
        bindings: {
            runtimeType: '@',
            statusName: '@',
            objectName: '@',
            isParentDependent: '<',
            extraPrimaryActionsConfig: '<'
        },
        template:
        `
          <pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
          <pf-table-view config="$ctrl.tableConfig"
                          columns="$ctrl.tableColumns"
                          action-buttons="$ctrl.tableActionButtons"
                          menu-actions="$ctrl.menuActions"
                          page-config="$ctrl.pageConfig"
                          items="$ctrl.viewedItems">
          </pf-table-view>
        `,
        controller: EntaxyTableController
    })
    .name;

    function EntaxyTableController(workspace, $location, $scope, $q, jolokia, jolokiaService, operationsService, entaxyService) {
        'ngInject';

        var ctrl = this;
        ctrl.workspace = workspace;

        let filterValues = Entaxy.getAllBundleStates();

        ctrl.tableConfig = {
            selectionMatchProp: 'displayName',
            showCheckboxes: false
        };

        ctrl.toolbarConfig = {
            filterConfig: {
                fields: [
                    {
                        id: 'displayName',
                        title: 'Name',
                        placeholder: 'Filter by Name...',
                        filterType: 'text'
                    },
                    {
                        id: 'status',
                        title: 'Status',
                        placeholder: 'Filter by Status...',
                        filterType: 'select',
                        filterValues: filterValues
                    }
                ],
                appliedFilters: [],
                onFilterChange: filterChange
            },
            isTableView: true
        };

        ctrl.tableColumns = [
            { header: 'Name', itemField: 'displayName' },
            { header: 'Status', itemField: 'status' }
        ];

        ctrl.pageConfig = Entaxy.getStandardPageConfig();

        function filterChange(filters) {
            ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
            ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
        };

        function matchesFilter(item, filter) {
            let match = true;
            if (filter.id === 'displayName') {
                match = item.displayName.match(filter.value) !== null;
            } else if (filter.id === 'status') {
                match = item.status === filter.value;
            }
            return match;
        };

        ctrl.items = [];
        ctrl.viewedItems = [];

        ctrl.$onInit = function() {
            populateTable();

            ctrl.itemType = Entaxy.capitalize(Entaxy.getItemTypeFromRuntimeType(ctrl.runtimeType));

            let primaryActions = [ { name: 'Add ' + ctrl.itemType, actionFn: () => ctrl.showModal(Entaxy.MODAL_MODES.ADD) } ];

            if (ctrl.extraPrimaryActionsConfig) {
                let extraPrimaryActions = ctrl.extraPrimaryActionsConfig.primaryActions;
                primaryActions = primaryActions.concat(extraPrimaryActions);

                if (ctrl.extraPrimaryActionsConfig.isTableUpdateNeeded) {
                    ctrl.extraPrimaryActionsConfig.updateTableFn = populateTable;
                }
            }

            ctrl.toolbarConfig.actionsConfig = {
                primaryActions: primaryActions
            };

            ctrl.tableActionButtons = [
                { name: 'Start', title: 'Start ' + ctrl.itemType, actionFn: startItem },
                { name: 'Stop', title: 'Stop ' + ctrl.itemType, actionFn: stopItem },
                { name: 'Uninstall', title: 'Uninstall ' + ctrl.itemType, actionFn: uninstallItem }
            ];

            ctrl.menuActions = [
                { name: 'View Properties', title: 'View ' + ctrl.itemType + ' Properties', actionFn: showPropertiesModal },
                { name: 'Edit Properties', title: 'Edit ' + ctrl.itemType + ' Properties', actionFn: showPropertiesModal }
            ];
        }

        function showPropertiesModal(action, item) {
            if (action.name === 'View Properties') {
                ctrl.showModal(Entaxy.MODAL_MODES.VIEW, item);
            } else if (action.name === 'Edit Properties') {
                ctrl.showModal(Entaxy.MODAL_MODES.EDIT, item);
            }
        }

        function populateTable() {
            let items = [];
            let promises = [];

            let selectedMBean = workspace.getSelectedMBean();
            if (selectedMBean && selectedMBean.isFolder) {
                let children = entaxyService.getAllChildMBeansByRuntimeType(selectedMBean, ctrl.runtimeType);

                if (children) {
                    children.forEach((child) => {
                        promises.push(jolokiaService.getAttributes(child.objectName, [ctrl.statusName, 'Name', 'DisplayName'])
                        .then((response) => {
                            items.push({
                                name: response['Name'],
                                displayName: response['DisplayName'] === '' || response['DisplayName'].startsWith('ERROR') ? response['Name'] : response['DisplayName'],
                                status: response[ctrl.statusName],
                                mbeanName: child.objectName
                            });
                        }));
                    });

                    $q.all(promises)
                    .then(() => {
                        ctrl.items = items;
                        ctrl.viewedItems = items;

                        let filters = ctrl.toolbarConfig.filterConfig.appliedFilters;
                        if (filters.length > 0) {
                            filterChange(filters);
                        } else {
                            ctrl.toolbarConfig.filterConfig.resultsCount = items.length;
                        }
                    });
                }
            }
        }

        ctrl.showModal = function(mode, item) {

            if (mode === Entaxy.MODAL_MODES.ADD) {

                let parentName;
                if (ctrl.isParentDependent === true) {
                    let selectedMbeanName = workspace.getSelectedMBeanName();
                    parentName = jolokia.getAttribute(selectedMbeanName, 'Name');
                }

                let resolve = {
                    mode: () => mode,
                    itemType: () => ctrl.itemType,
                    parentName: () => parentName
                };

                entaxyService.openAddItemModalAndProcessResults(resolve, updateLocation);
            } else {
                let mbeanName = workspace.getSelectedMBeanName();
                entaxyService.openEditItemModalAndProcessResults(mbeanName, ctrl.itemType, item.name, mode);
            }
        }

        function updateLocation(properties, objectId) {
            if (!ctrl.isParentDependent) {
                changeLocation(properties[ctrl.objectName] ? properties[ctrl.objectName] : objectId);
            }
        }

        function changeLocation(itemName) {
            let currentLocation = $location.search();
            $location.search('nid', currentLocation.nid + '-' + itemName);
        }

        $scope.$on(Jmx.TreeEvent.Updated, () => {
            populateTable();
        });

        function startItem(action, item) {
            if (item.status !== 'Active') {
                processOperation('start', item.name);
            } else {
                Core.notification('info', ctrl.itemType + ' has been already started');
            }
        }

        function stopItem(action, item) {
            if (item.status !== 'Resolved') {
                processOperation('stop', item.name);
            } else {
                Core.notification('info', ctrl.itemType + ' has been already stopped');
            }
        }

        function uninstallItem(action, item) {
            let operationName = ctrl.isParentDependent ? 'remove' : 'uninstall';

            let title = 'Confirm Uninstalling';
            let message = 'Do you want to uninstall ' + ctrl.itemType.toLowerCase() + ' ' + item.displayName + '?';

            entaxyService.openConfirmationWindow(title, message).then(() => {
                processOperation(operationName, item.name);
            });
        }

        function processOperation(operationName, selectedItemName) {
            let mbeanName = workspace.getSelectedMBeanName();
            let operation = { name: operationName + ctrl.itemType };

            entaxyService.processTableOperation(mbeanName, operation, selectedItemName);
        }

        ctrl.dismissAlert = () => ctrl.alert = null;

    }
    EntaxyTableController.$inject = ['workspace', '$location', '$scope', '$q', 'jolokia', 'jolokiaService', 'operationsService', 'entaxyService'];

})(Entaxy || (Entaxy = {}));
