/*-
 * ~~~~~~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('entaxyAllConnectorsTable', {
        template:
        `
          <h2>
            Connectors
          </h2>

          <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: EntaxyAllConnectorsTableController
    })
    .name;

    function EntaxyAllConnectorsTableController($q, workspace, $scope, operationsService,
                                                jolokia, jolokiaService, entaxyService,
                                                entaxyLegacyConnectorService, entaxyAttributesCacheService) {
        'ngInject';

        let ctrl = this;
        ctrl.workspace = workspace;

        ctrl.itemName = 'Connector';
        ctrl.statusName = 'BundleState';
        const CONTAINER_TYPE_PROFILE = 'Profile';

        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: 'direction',
                        title: 'Direction',
                        placeholder: 'Filter by Direction...',
                        filterType: 'select',
                        filterValues: ['in', 'out']
                    },
                    {
                        id: 'type',
                        title: 'Type',
                        placeholder: 'Filter by Type...',
                        filterType: 'text'
                    },
                    {
                        id: 'profile',
                        title: 'Profile',
                        placeholder: 'Filter by Profile...',
                        filterType: 'select',
                        filterValues: []
                    },
                    {
                        id: 'status',
                        title: 'Status',
                        placeholder: 'Filter by Status...',
                        filterType: 'select',
                        filterValues: filterValues
                    }
                ],
                appliedFilters: [],
                onFilterChange: filterChange
            },
            isTableView: true
        };

        ctrl.tableColumns = [
            { header: 'Direction', itemField: 'direction' },
            { header: 'Name', itemField: 'displayName' },
            { header: 'Type', itemField: 'type' },
            { header: 'Profile', itemField: 'profile' },
            { 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 === 'direction') {
                match = item.direction === filter.value;
            } else if (filter.id === 'displayName') {
                match = item.displayName.match(filter.value) !== null;
            } else if (filter.id === 'type') {
                match = item.type.match(filter.value) !== null;
            } else if (filter.id === 'profile') {
                match = item.profile === filter.value;
            } else if (filter.id === 'status') {
                match = item.status === filter.value;
            }
            return match;
        };

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

        ctrl.$onInit = function() {

            entaxyService.getProfiles().then(profiles => {
                ctrl.profiles = profiles.sort(Entaxy.compareBy('name'));
                populateTable();

                let toolbarConfigFilterProfile = ctrl.toolbarConfig.filterConfig.fields
                    .find(field => field.id === 'profile');
                toolbarConfigFilterProfile.filterValues = ctrl.profiles.map(profile => profile.name);

                let primaryActions = [
                    {
                        name: 'Add Connector',
                        actionFn: () => ctrl.showModal(Entaxy.MODAL_MODES.ADD),
                        isDisabled: ctrl.profiles.length === 0
                    }//,
                    // {
                    //     name: 'Add Legacy Connector',
                    //     actionFn: () => ctrl.showAddLegacyConnectorModal(),
                    //     isDisabled: ctrl.profiles.length === 0
                    // }
                ];

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

            ctrl.tableActionButtons = [
                { name: 'Start', title: 'Start ' + ctrl.itemName, actionFn: checkAndProcess },
                { name: 'Stop', title: 'Stop ' + ctrl.itemName, actionFn: checkAndProcess },
                { name: 'Edit', title: 'Edit ' + ctrl.itemName + ' Properties', actionFn: showPropertiesModal },
                { name: 'Use As Template', title: 'Use As Template', actionFn: addConnectorFromTemplate }
            ];

            ctrl.menuActions = [
                { name: 'Uninstall', title: 'Uninstall ' + ctrl.itemName, actionFn: checkAndProcess },
                { name: 'View Properties', title: 'View ' + ctrl.itemName + ' Properties', actionFn: showPropertiesModal }
            ];
        }

        function showPropertiesModal(action, item) {
            if (action.name === 'View Properties') {
                ctrl.showModal(Entaxy.MODAL_MODES.VIEW, item);
            } else if (action.name === 'Edit') {
                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 profilesFolder = entaxyService.getDomainFolder()
                .findDescendant(child => child.objectName && child.objectName.endsWith('category=profiles'));

            entaxyService.getAllChildMBeansByRuntimeType(profilesFolder, Entaxy.RUNTIME_TYPE.CONNECTOR)
            .then((mbeans) => {

                mbeans.forEach(mbean => {
                    let connectorSystemName = mbean.attributes.System;
                    let profile = ctrl.profiles.find(profile => profile.name === connectorSystemName);
                    let displayName =
                        mbean.attributes.DisplayName && mbean.attributes.DisplayName.trim().length > 0 ?
                            mbean.attributes.DisplayName : mbean.attributes.Name;
                    let factoryId = mbean.attributes.FactoryId;
                    let factoryFolder = entaxyService.getFolderByTitle(factoryId);
                    if (factoryFolder) {
                        jolokiaService.getAttribute(factoryFolder.objectName, 'TypeInfo')
                        .then(typeInfo => {
                            items.push({
                                name: mbean.attributes.Name,
                                displayName: displayName,
                                direction: mbean.attributes.Direction ? mbean.attributes.Direction : '-',
                                type: typeInfo.type,
                                status: mbean.attributes[ctrl.statusName],
                                mbeanName: mbean.mbean.objectName,
                                profileMBeanName: profile.mbeanName,
                                profile: profile.name
                            });
                        });
                    }
                });

                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) {

            let runtimeType = Entaxy.RUNTIME_TYPE.CONNECTOR;

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

                let resolve = {
                    mode: () => mode,
                    itemType: () => ctrl.itemName,
                    containerType: () => CONTAINER_TYPE_PROFILE,
                    containers: () => ctrl.profiles
                };

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

        function addConnectorFromTemplate(action, item) {
            let resolve = {
                itemType: () => ctrl.itemName,
                containerType: () => CONTAINER_TYPE_PROFILE,
                containers: () => ctrl.profiles
            };
            entaxyService.openAddItemFromTemplateModalAndProcessResults(resolve, item, Entaxy.RUNTIME_TYPE.CONNECTOR);
        }

        ctrl.showAddLegacyConnectorModal = function() {
            let resolve = {
                profiles: () => ctrl.profiles
            };

            entaxyLegacyConnectorService.openAddLegacyConnectorModal(resolve).then(connectorArgs => {
                addLegacyConnector(connectorArgs);
            });
        }

        function addLegacyConnector(connectorArgs) {

            let args = entaxyLegacyConnectorService.getArguments(connectorArgs);
            let mbeanName = connectorArgs.profile.mbeanName;

            operationsService.executeOperation(mbeanName, { name: 'addConnector' }, args)
            .then(result => {
                Entaxy.notificationSuccess(result);
            }).catch(error => {
                Entaxy.notificationError(error);
            });
        }

        $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.itemName.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, Entaxy.RUNTIME_TYPE.CONNECTOR, item.displayName);
            } else {
                Entaxy.notificationInfo(ctrl.itemName + ' has been already started');
            }
        }

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

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

            entaxyService.openConfirmationWindow(title, message).then(() => {
                entaxyService.processTableOperation(Entaxy.OPERATION_TYPE.UNINSTALL,
                    item.name, Entaxy.RUNTIME_TYPE.CONNECTOR, item.displayName);
                entaxyAttributesCacheService.removeFromCache(item.mbeanName);
            });
        }

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

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

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