/*
 * 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.
 */
import angular from "angular";
import template from './stream.template.html';

const MODULE_NAME = 'inspector.stream';

angular.module(MODULE_NAME, [])
    .directive('stream', streamDirective);

export default MODULE_NAME;

export function streamDirective() {
    return {
        template: template,
        restrict: 'E',
        scope: {
            autoUpdate: '=?',
            tail: '=?',
            activityId: '@',
            streamType: '@',
        },
        controller: ['$scope', '$interval', '$element', 'activityApi', controller]
    };

    function controller($scope, $interval, $element, activityApi) {
        $scope.autoUpdate = $scope.autoUpdate !== false;
        $scope.tail = $scope.tail !== false;

        // Content filtering features
        $scope.filteredStream = [];
        $scope.streamProcessedUpTo = 0;
        $scope.otherLogLines = 0;
        $scope.errorLogLines = 0;
        $scope.debugLogLines = 0;
        $scope.traceLogLines = 0;
        $scope.warningLogLines = 0;
        $scope.isDisplayOther = $scope.isDisplayOther !== false;
        $scope.isDisplayError = $scope.isDisplayError !== false;
        $scope.isDisplayDebug = $scope.isDisplayDebug !== false;
        $scope.isDisplayTrace = $scope.isDisplayTrace !== false;
        $scope.isDisplayWarning = $scope.isDisplayWarning !== false;
        $scope.isFilterContent = isFilterContent;
        $scope.isDisplayFormattedItem = isDisplayFormattedItem;
        $scope.getFormattedItemLogLevel = getFormattedItemLogLevel;

        // CLI XML features
        $scope.cliXml = false;
        $scope.cliXmlIdentified = false;
        $scope.toggleCliXml = toggleCliXml;
        $scope.isCliXmlSupported = isCliXmlSupported;
        $scope.cliXmlVerificationRequired = isWinRmStream(); // CLI XML verification is required only when stream is WinRM

        let autoScrollableElement = Array.from($element.find('pre')).filter(item => item.classList.contains('auto-scrollable'));
        let refreshFunction;

        // Set up cancellation of auto-scrolling on scrolling up.
        autoScrollableElement.forEach(item => {
            if (item.addEventListener)
            {
                let wheelHandler = () => {
                    $scope.$apply(() => {
                        $scope.tail = (item.scrollTop + item.offsetHeight) >= item.scrollHeight;
                    });
                }
                // IE9, Chrome, Safari, Opera
                item.addEventListener("mousewheel", wheelHandler, false);
                // Firefox
                item.addEventListener("DOMMouseScroll", wheelHandler, false);
            }
        });

        // Watch the 'tail' and auto-scroll down if auto-scroll is enabled.
        $scope.$watch('tail', () => {
            if ($scope.tail) {
                $scope.$applyAsync(() => {
                    autoScrollableElement.forEach(item => item.scrollTop = item.scrollHeight);
                });
            }
        });

        $scope.$watch('autoUpdate', ()=> {
            if ($scope.autoUpdate) {
                refreshFunction = $interval(updateStream, 1000);
            } else {
                cancelUpdate();
            }
        });
        $scope.$on('$destroy', cancelUpdate);

        /**
         * Updates the stream data.
         */
        function updateStream() {
            activityApi.activityStream($scope.activityId, $scope.streamType).then((response)=> {

                // 1. Try to identify CLI XML output.
                const CLI_XML_HEADER_SIZE = 100; // estimated headers size in WinRM that can contain indication of CLI XML output
                if ($scope.cliXmlVerificationRequired && typeof response.data === 'string' && response.data.length >= CLI_XML_HEADER_SIZE) {
                    let header = response.data.slice(0, CLI_XML_HEADER_SIZE);
                    if (header.includes('#< CLIXML') || header.includes('xmlns="http://schemas.microsoft.com/powershell')) {
                        $scope.cliXmlIdentified = true;
                    }
                    $scope.cliXmlVerificationRequired = false; // perform verification once, if conditions match
                }

                // 2. Update the stream data holder in this directive.
                $scope.stream = response.data;

                // 3. Filter the content where relevant and display it.
                updateFilteredContent();

            }).catch((error)=> {
                if (error.data) {
                    $scope.error = error.data.message;
                }
            }).finally(() => {
                if ($scope.tail) {
                    $scope.$applyAsync(() => {
                        autoScrollableElement.forEach(item => item.scrollTop = item.scrollHeight);
                    });
                }
            })
        }

        /**
         * Cancels the auto-update of the streamed content.
         */
        function cancelUpdate() {
            if (refreshFunction) {
                $interval.cancel(refreshFunction);
            }
        }

        /**
         * @returns {boolean} True if CLI XML is supported, and false otherwise. CLI XML is expected in WinRM stream only.
         */
        function isCliXmlSupported() {
            return isWinRmStream() && $scope.cliXmlIdentified === true;
        }

        /**
         * @returns {boolean} True if stream type is WinRM, and false otherwise.
         */
        function isWinRmStream() {
            return $scope.streamType === 'winrm';
        }

        /**
         * Switches content format to CLI XML and back.
         */
        function toggleCliXml() {
            $scope.cliXml = !$scope.cliXml;
            updateFilteredContent();
        }

        /**
         * @returns {boolean} True if logging filter should be displayed, and false otherwise.
         */
        function isFilterContent() {
            return isCliXmlSupported() && $scope.cliXml !== true;
        }

        /**
         * @returns {string} Returns class name of the formatted item log level.
         */
        function getFormattedItemLogLevel(formattedItem) {
            if (formattedItem.isWarning) {
                return 'log-warning';
            } else  if (formattedItem.isError) {
                return 'log-error';
            } if (formattedItem.isDebug) {
                return 'log-debug';
            }
            return 'log-trace';
        }

        /**
         * @returns {boolean} True if formatted item should be displayed, and false otherwise.
         */
        function isDisplayFormattedItem(formattedItem) {
            return formattedItem.isWarning && $scope.isDisplayWarning
                || formattedItem.isDebug && $scope.isDisplayDebug
                || formattedItem.isError && $scope.isDisplayError
                || formattedItem.isTrace && $scope.isDisplayTrace
                || formattedItem.isOther && $scope.isDisplayOther;
        }

        /**
         * Formats CLI XML output and displays it in 'filtered-stream-content' field.
         */
        function formatCliXmlContent() {

            // Slice at index of last closing tag ending wth the new line
            let streamTags = $scope.stream.match(/<\/(.*?)>\n/g);
            let lastClosingTagIndex  = $scope.stream.lastIndexOf(streamTags[streamTags.length-1]);
            let newCliXmlData = $scope.stream.slice($scope.streamProcessedUpTo, lastClosingTagIndex);
            if (!newCliXmlData) {
                return;
            }

            $scope.streamProcessedUpTo += newCliXmlData.length;

            newCliXmlData.split(/\n/g).forEach(item => {
                let formattedItem = {
                    id: ($scope.filteredStream.length), // ng-repeat requires unique items, array length fits the bill
                    text: item,
                    isOther: false,
                    isError: false,
                    isDebug: false,
                    isTrace: false,
                    isWarning: false
                };

                if (/<s s="warning">/i.test(item)) {
                    $scope.warningLogLines++;
                    formattedItem.isWarning = true;
                } else if (/<s s="debug">/i.test(item)) {
                    $scope.debugLogLines++;
                    formattedItem.isDebug = true;
                } else if (/<s s="verbose">/i.test(item)) {
                    $scope.traceLogLines++;
                    formattedItem.isTrace = true;
                } else if (/<s s="error">/i.test(item)) {
                    $scope.errorLogLines++;
                    formattedItem.isError = true;
                } else {
                    $scope.otherLogLines++;
                    formattedItem.isOther = true;
                }

                // Remove CLI XML string tags for know log levels
                if (!formattedItem.isOther) {
                    formattedItem.text = item.replace(/<s s="(.*?)">|\t/gi, '');
                }

                // Remove CLI XML markers, newlines and replace tabs with spaces
                formattedItem.text = formattedItem.text.replace(/<\/s>|_x000[a-z0-9]_|\n/gi, '').replace(/\t/g,' ');

                // Push update item and let ng-repeat update the content
                $scope.filteredStream.push(formattedItem);
            });
        }

        /**
         * Filters stream content as per selected filters if filtering is enabled, e.g. display/hide warnings or errors.
         */
        function updateFilteredContent() {

            if (!isFilterContent()) {
                return;
            }

            // Format new CLI XML content
            if (isCliXmlSupported()) {
                formatCliXmlContent();
            }
        }

        updateStream();
    }
}

