/*-
 * ~~~~~~licensing~~~~~~
 * entaxy-management-plugin
 * ==========
 * Copyright (C) 2020 - 2024 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('entaxyResources', {
        template:
        `
          <div class="resources-header-container">
            <h2>
              Resources
            </h2>
            <p class="text-muted">{{$ctrl.location}}</p>
            <entaxy-copy-to-clipboard-button title="Copy location to clipboard"
                    text-to-copy="$ctrl.location"></entaxy-copy-to-clipboard-button>
            <button type="button" data-toggle="tooltip" title="Change location view"
                    ng-click="$ctrl.changeLocationView()">
              <span class="fa pficon-optimize"></span>
            </button>
            <div class="divider"></div>
            <button type="button" data-toggle="tooltip" title="Upload resource" ng-click="$ctrl.triggerUpload()">
              <span class="fa fa-upload"></span>
              <input type="file" id="file-input" name="file-input" set-file-model
                    ng-model="$ctrl.file" ng-change="$ctrl.upload($ctrl.file)">
            </button>
            <button type="button" data-toggle="tooltip" title="Change to list" ng-click="$ctrl.changeView('list')"
                    ng-if="$ctrl.view === 'tiles'">
              <span class="fa fa-list"></span>
            </button>
            <button type="button" data-toggle="tooltip" title="Change to tiles" ng-click="$ctrl.changeView('tiles')"
                    ng-if="$ctrl.view === 'list'">
              <span class="fa fa-th"></span>
            </button>
          </div>

          <entaxy-crumbs root-crumb="$ctrl.protocol" crumbs="$ctrl.crumbs"></entaxy-crumbs>

          <div class="resources-file-drop-zone" entaxy-file-drop ng-model="$ctrl.file"
                process-fn="$ctrl.upload($ctrl.file)">
            <div class="file-panel-container" context-menu context-menu-options="$ctrl.contextMenuOptions">
              <entaxy-file-panel items="$ctrl.items" selected-item="$ctrl.selectedItem" view="$ctrl.view"
                    change-selection-fn="$ctrl.changeSelection" open-fn="$ctrl.open"
                    resource-context-menu-options="$ctrl.resourceContextMenuOptions"
                    folder-context-menu-options="$ctrl.folderContextMenuOptions"></entaxy-file-panel>
            </div>
            <div class="meta-info" resizable r-directions="['left']"
                    ng-if="$ctrl.selectedItem && $ctrl.selectedItem.metadata">
              <uib-tabset active="$ctrl.activeTab" class="meta-tabs">
                <uib-tab ng-repeat="(section, info) in $ctrl.selectedItem.metadata track by $index"
                        heading="{{section}}">
                  <div class="json-formatter">
                    <json-formatter json="info" open="1"></json-formatter>
                  </div>
                </uib-tab>
              </uib-tabset>
            </div>
          </div>
        `,
        controller: entaxyResourcesController
    })
    .name;

    function entaxyResourcesController(workspace, $scope, jolokia, entaxyService, entaxyResourcesService,
                                       $timeout, $uibModal, $cookies) {
        'ngInject';

        let ctrl = this;
        let selectedMbeanName = workspace.getSelectedMBeanName();
        let clientFolders = [];
        const ENTAXY_RESOURCE_PREFIX = 'entaxy-resource://';
        ctrl.isFullLocationView = true;

        ctrl.contextMenuOptions = [
            {
                name: 'Create folder',
                actionFn: createFolder
            },
            {
                name: 'Upload',
                actionFn: uploadResource
            },
            {
                name: 'Paste',
                actionFn: pasteResource
            }
        ];


        ctrl.resourceContextMenuOptions = [
            {
                name: 'Download',
                actionFn: downloadResource
            },
            {
                name: 'Copy',
                actionFn: copyResource
            },
            {
                name: 'Cut',
                actionFn: cutResource
            },
            {
                name: 'Remove',
                actionFn: removeResource
            },
            {
                divider: true
            }
        ].concat(ctrl.contextMenuOptions);

        ctrl.folderContextMenuOptions = [
            {
                name: 'Paste to folder',
                actionFn: pasteResourceToFolder
            },
            {
                name: 'Remove',
                actionFn: removeResource
            },
            {
                divider: true
            }
        ].concat(ctrl.contextMenuOptions);

        ctrl.$onInit = function () {
            ctrl.view = 'list';
            ctrl.protocol = jolokia.getAttribute(selectedMbeanName, 'Protocol');
            let path = $cookies.getObject(ctrl.protocol);
            ctrl.crumbs = path ? path.split('/') : [];
        }

        $scope.$watchCollection('$ctrl.crumbs', function() {
            ctrl.selectedItem = null;
            ctrl.location = ctrl.isFullLocationView ? getFullLocation() : getLocation();

            $cookies.putObject(ctrl.protocol, getPath());

            updateItems();
        })

        ctrl.changeView = function (view) {
            ctrl.view = view;
        }

        ctrl.changeLocationView = function () {
            ctrl.location = ctrl.isFullLocationView ? getLocation() : getFullLocation();
            ctrl.isFullLocationView = !ctrl.isFullLocationView;
        }

        ctrl.changeSelection = function (item) {
            ctrl.selectedItem = item;
            ctrl.location = ctrl.isFullLocationView ? getFullLocation() : getLocation();
            $timeout(function () {
                ctrl.activeTab = 0;
            });
        }

        ctrl.open = function (item) {
            if (item.isFolder === true) {
                ctrl.crumbs.push(item.name);
            }
        }

        function updateItems() {
            let path = getPath();

            entaxyResourcesService.getResourcesInfo(selectedMbeanName, path)
            .then(originItems => {
                items = originItems
                    .concat(entaxyResourcesService.getClientFoldersToAdd(clientFolders, originItems, ctrl.crumbs));
                ctrl.items = items.sort(Entaxy.compareBy('name')).sort((a, b) => b.isFolder - a.isFolder);
            })
        }

        function getPath() {
            return entaxyResourcesService.getPath(ctrl.crumbs);
        }

        function getLocationWithoutProtocol(folderSelectionEnabled) {
            let isItemSelected = ctrl.selectedItem &&
                (!ctrl.selectedItem.isFolder || (folderSelectionEnabled && ctrl.selectedItem.isFolder));
            let separator = getPath().length > 0 && isItemSelected ? '/' : '';
            let selectedItemName = isItemSelected ? ctrl.selectedItem.name : '';
            return getPath() + separator + selectedItemName;
        }

        function getLocation(folderSelectionEnabled) {
            return ctrl.protocol + ':' + getLocationWithoutProtocol(folderSelectionEnabled);
        }

        function getFullLocation() {
            return ENTAXY_RESOURCE_PREFIX + ctrl.protocol + '/' + getLocationWithoutProtocol();
        }

        function createFolder() {
            entaxyResourcesService.addFolder(ctrl.items, clientFolders, ctrl.crumbs);
        }

        function uploadResource() {
            ctrl.triggerUpload();
        }

        function downloadResource(item) {

            let path = isItemSelected(item) ?
                getLocationWithoutProtocol(true) :
                getLocationWithoutProtocol(true) + '/' + item.name;

            entaxyResourcesService.downloadResource(selectedMbeanName, path)
            .then(result => {
                entaxyService.downloadFileFromBase64StringContent(result, item.name);
            }).catch(error => {
                Entaxy.notificationError(error);
                Entaxy.log.error(error);
            });
        }

        function copyResource(item) {
            setCopyConfig(item, false);
        }

        function cutResource(item) {
            setCopyConfig(item, true);
        }

        function setCopyConfig(item, removeSource) {
            Entaxy.resourceCopyConfig.sourceResourcePath = isItemSelected(item) ?
                getLocation(true) : getLocation(true) + '/' + item.name;
            Entaxy.resourceCopyConfig.sourceResourceName = item.name;
            Entaxy.resourceCopyConfig.removeSource = removeSource;
        }

        function pasteResource() {
            if (Entaxy.resourceCopyConfig.sourceResourcePath) {
                let path = getPath();
                pasteWithUniquenessCheck(ctrl.items, path);
            }
        }

        function pasteResourceToFolder(item) {
            if (Entaxy.resourceCopyConfig.sourceResourcePath) {
                let path = isItemSelected(item) ?
                    getLocationWithoutProtocol(true) :
                    getLocationWithoutProtocol(true) + '/' + item.name;

                entaxyResourcesService.getResourcesInfo(selectedMbeanName, path)
                .then(items => {
                    pasteWithUniquenessCheck(items, path);
                })
                .catch((error) => {
                    Entaxy.log.error(error);
                    Entaxy.notificationError('An error occurred while getting resources.');
                });
            }
        }

        function pasteWithUniquenessCheck(items, path) {

            let copiedDuplicateItem = items.find(item => item.name === Entaxy.resourceCopyConfig.sourceResourceName);
            if (copiedDuplicateItem && !copiedDuplicateItem.isFolder) {
                $uibModal.open({
                    component: 'entaxySimpleResourceNameInputModal',
                    resolve: {
                        title: () => 'Change resource name',
                        names: () => items.filter((item) => !item.isFolder).map((item) => item.name),
                        name: () => Entaxy.resourceCopyConfig.sourceResourceName,
                        type: () => 'Resource'
                    },
                    size: 'sm-custom',
                    backdrop: 'static',
                    windowTopClass: 'modal-top-margin-center-override'
                })
                .result.then(name => {
                    paste(Entaxy.resourceCopyConfig.sourceResourcePath, path, name);
                });
            } else {
                paste(Entaxy.resourceCopyConfig.sourceResourcePath, path, Entaxy.resourceCopyConfig.sourceResourceName);
            }
        }

        function paste(from, to, name) {
            const fullToPath = to + '/' + name;
            entaxyResourcesService.pasteResource(selectedMbeanName, from, fullToPath)
            .then(result => {
                if (Entaxy.resourceCopyConfig.removeSource) {
                    entaxyResourcesService.removeResource(selectedMbeanName,
                        Entaxy.resourceCopyConfig.sourceResourcePath)
                    .then(result => {
                        Entaxy.resourceCopyConfig.sourceResourcePath = ctrl.protocol + ':' + fullToPath;
                        Entaxy.resourceCopyConfig.sourceResourceName = name;
                        Entaxy.resourceCopyConfig.removeSource = false;
                        updateItems();
                    }).catch(error => {
                        Entaxy.notificationError(error);
                        Entaxy.log.error(error);
                    });
                } else {
                    updateItems();
                }
            }).catch(error => {
                Entaxy.notificationError(error);
                Entaxy.log.error(error);
            });
        }

        function removeResource(item) {
            let title = 'Confirm Removing Resource';
            let resourceType = item.isFolder ? 'folder' : 'resource';
            let message = 'Do you want to remove ' + resourceType + ' ' + item.name + '?';

            entaxyService.openConfirmationWindow(title, message)
            .then(() => {
                let path = isItemSelected(item) ?
                    getLocationWithoutProtocol(true) :
                    getLocationWithoutProtocol(true) + '/' + item.name;
                entaxyResourcesService.removeResource(selectedMbeanName, path)
                .then((result) => {
                    Entaxy.notificationSuccess('Resource ' + item.name + ' was successfully removed');
                    if (isItemSelected(item)) {
                        ctrl.selectedItem = undefined;
                    }
                    updateItems();
                })
                .catch((error) => {
                    Entaxy.log.error(error);
                    Entaxy.notificationError('An error occurred while removing resource ' + item.name);
                });
            });
        }

        function isItemSelected(item) {
            return ctrl.selectedItem && ctrl.selectedItem.name === item.name;
        }

        ctrl.triggerUpload = function () {
            document.getElementById('file-input').click();
        }

        ctrl.upload = function (file) {
            let separator = getPath().length > 0 ? '/' : '';
            let uploadPromise = entaxyResourcesService
                .uploadFile(file, ctrl.protocol, getPath() + separator + file.name);

            if (uploadPromise) {
                uploadPromise.then((response) => {
                    Entaxy.notificationSuccess('File ' + response.data + ' was successfully uploaded.');
                    updateItems();
                })
                .catch((error) => {
                    Entaxy.log.error(error);
                    Entaxy.notificationError('An error occurred while uploading the file.');
                });
            }
        }
    }
    entaxyResourcesController.$inject = ['workspace', '$scope', 'jolokia', 'entaxyService', 'entaxyResourcesService',
        '$timeout', '$uibModal', '$cookies'];

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