/*-
 * ~~~~~~licensing~~~~~~
 * entaxy-management-plugin
 * ==========
 * Copyright (C) 2020 - 2025 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: '<',
            populationParentMbeanName: '<',
            skipLocationUpdate: '<'
        },
        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, entaxyAttributesCacheService) {
        '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.toLowerCase().match(filter.value.toLowerCase()) !== null;
            } else if (filter.id === 'status') {
                match = item.status === filter.value;
            }
            return match;
        }

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

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

            ctrl.itemType = 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: checkAndProcess },
                { name: 'Stop', title: 'Stop ' + ctrl.itemType, actionFn: checkAndProcess },
                { name: 'Edit', title: 'Edit ' + ctrl.itemType + ' Properties', actionFn: showPropertiesModal }
            ];

            ctrl.menuActions = [
                { name: 'Uninstall', title: 'Uninstall ' + ctrl.itemType, actionFn: checkAndProcess },
                { name: 'View Properties', title: 'View ' + 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') {
                if (ctrl.runtimeType === Entaxy.RUNTIME_TYPE.CONNECTION && item.isPlatform) {
                    ctrl.showModal(Entaxy.MODAL_MODES.VIEW, item);
                    return;
                }
                entaxyService.readObjectClusterState(item.mbeanName).then(objectClusterState => {
                    if (objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.NON_CLUSTERED) {
                        Entaxy.notificationInfo(Entaxy.NON_CLUSTERED_MESSAGE.OPERATIONS);
                    } else {
                        item.isLocal = objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.LOCAL;
                        ctrl.showModal(Entaxy.MODAL_MODES.EDIT, item);
                    }
                }).catch(e => Entaxy.notificationError(e));
            }
        }

        function populateTable() {
            let items = [];

            let selectedMBean = ctrl.populationParentMbeanName ?
                entaxyService.getDomainFolder()
                    .findDescendant(child => child.objectName === ctrl.populationParentMbeanName) :
                workspace.getSelectedMBean();
            if (selectedMBean && selectedMBean.isFolder) {
                entaxyService.getAllChildMBeansByRuntimeType(selectedMBean, ctrl.runtimeType).then((mbeans) => {
                    mbeans.forEach((mbean) => {
                        let displayName = mbean.attributes.DisplayName &&
                            mbean.attributes.DisplayName.trim().length > 0 ?
                            mbean.attributes.DisplayName : mbean.attributes.Name;
                        items.push({
                            name: mbean.attributes.Name,
                            displayName: displayName,
                            status: mbean.attributes[ctrl.statusName],
                            mbeanName: mbean.mbean.objectName,
                            isPlatform: mbean.attributes.Platform
                        });
                    });

                    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 parentMBeanName = ctrl.populationParentMbeanName ?
                    ctrl.populationParentMbeanName : workspace.getSelectedMBeanName();

                let parentName = ctrl.isParentDependent === true ?
                    jolokia.getAttribute(parentMBeanName, 'Name') : undefined;

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

                entaxyService.openAddItemModalAndProcessResults(resolve, ctrl.runtimeType, updateLocation);
            } else {
                entaxyService.openEditItemModalAndProcessResults(item, ctrl.itemType, ctrl.runtimeType, mode);
            }
        }

        function updateLocation(properties, objectId) {
            if (!ctrl.skipLocationUpdate) {
                let itemName =
                    ctrl.runtimeType === Entaxy.RUNTIME_TYPE.REPOSITORY ||
                        ctrl.runtimeType === Entaxy.RUNTIME_TYPE.ROUTE_LIBRARY ?
                    objectId + '_' + ctrl.runtimeType :
                    properties[ctrl.objectName] ? properties[ctrl.objectName] : objectId;
                changeLocation(itemName);
            }
        }

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

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

        function checkAndProcess(action, item) {
            entaxyService.readObjectClusterState(item.mbeanName).then(objectClusterState => {
                if (objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.LOCAL) {
                    Entaxy.notificationInfo('Local ' + ctrl.itemType.toLowerCase() + ' cannot be ' +
                        action.name.toLowerCase() +
                        (action.name.toLowerCase() === Entaxy.OPERATION_TYPE.STOP ? 'ped' : 'ed'));
                } else if (objectClusterState === Entaxy.OBJECT_CLUSTER_STATE.NON_CLUSTERED) {
                    Entaxy.notificationInfo(Entaxy.NON_CLUSTERED_MESSAGE.OPERATIONS);
                } else {
                    switch (action.name.toLowerCase()) {
                        case Entaxy.OPERATION_TYPE.START:
                            startItem(action, item);
                            return;
                        case Entaxy.OPERATION_TYPE.STOP:
                            stopItem(action, item);
                            return;
                        case Entaxy.OPERATION_TYPE.UNINSTALL:
                            uninstallItem(action, item);
                            return;
                    }
                }
            }).catch(e => Entaxy.notificationError(e));
        }

        function startItem(action, item) {
            if (item.status !== 'Active') {
                entaxyAttributesCacheService.setToUpdate(item.mbeanName);
                entaxyService.processTableOperation(Entaxy.OPERATION_TYPE.START,
                    item.name, ctrl.runtimeType, item.displayName);
            } else {
                Entaxy.notificationInfo(ctrl.itemType + ' has been already started');
            }
        }

        function stopItem(action, item) {
            if (item.status !== 'Resolved') {
                entaxyAttributesCacheService.setToUpdate(item.mbeanName);
                entaxyService.processTableOperation(Entaxy.OPERATION_TYPE.STOP,
                    item.name, ctrl.runtimeType, item.displayName);
            } else {
                Entaxy.notificationInfo(ctrl.itemType + ' has been already stopped');
            }
        }

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

            entaxyService.openConfirmationWindow(title, message).then(() => {
                let selectedFolder = entaxyService.getDomainFolder()
                    .findDescendant(child => child.objectName === item.mbeanName);
                let children = Entaxy.getChildrenRecursive(selectedFolder);
                entaxyAttributesCacheService.removeFromCache(item.mbeanName);
                if (children) {
                    children.forEach(child => entaxyAttributesCacheService.removeFromCache(child.objectName));
                }
                entaxyService.processTableOperation(Entaxy.OPERATION_TYPE.UNINSTALL,
                    item.name, ctrl.runtimeType, item.displayName);
            });
        }

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

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

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