/*
 * 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 './server-status.less';

import angular from 'angular';
import uibModal from 'angular-ui-bootstrap/src/modal/index-nocss';
import modalTemplate from './server-status.template.html';

const MODULE_NAME = 'br.utils.server-status';
const COOKIE_KEY = "br-server-status";
const COOKIE_EXPIRY = 15 * 60000;
const REFRESH_INTERVAL = 15000;
const DEFAULT_COOKIE = {dismissed: false};

angular.module(MODULE_NAME, [uibModal])
    .directive('brServerStatus', BrServerStatusDirective);

export default MODULE_NAME;

export function BrServerStatusDirective() {
    return {
        restrict: 'A',
        controller: ['$rootScope', '$scope', '$http', '$cookies', '$interval', '$uibModal', '$log', controller]
    };

    function controller($rootScope, $scope, $http, $cookies, $interval, $uibModal, $log) {
        let cookie = DEFAULT_COOKIE;
        let intervalId = $interval(checkStatus, REFRESH_INTERVAL);
        $scope.$on('$destroy', () => ($interval.cancel(intervalId)));
        let modalInstance = null;
        var previousState = null;

        function checkStatus() {
            cookie = $cookies.getObject(COOKIE_KEY) || DEFAULT_COOKIE;
            $http({method: 'GET', url: '/v1/server/up/extended'})
                .then(updateState, (error) => (updateState(error, true)));
        }

        function updateState(response, error = false) {
            let state = BrServerStatusModalController.STATES.OK;
            let stateData = null;
            if (error) {
                stateData = response.data;

                if (stateData && stateData.SESSION_AGE_EXCEEDED) {
                    state = BrServerStatusModalController.STATES.SESSION_AGE_EXCEEDED;
                } else if (stateData && stateData.SESSION_INVALIDATED) {
                    state = BrServerStatusModalController.STATES.SESSION_INVALIDATED;
                }else if(response.status === 404) {
                    state = BrServerStatusModalController.STATES.NO_CONNECTION;
                }else if(response.status === 401 || response.status === 403 ) {
                    state = BrServerStatusModalController.STATES.USER_NOT_AUTHORIZED;
                }else {
                    if (previousState === null || previousState == BrServerStatusModalController.STATES.OK){
                        state = BrServerStatusModalController.STATES.OTHER_ERROR;
                    } else {
                        // we're now getting a new server error, possibly because the old error has expired
                        // but changing the message for the user would be confusing so don't do that!
                        // eg we get a 405 after a 307 (which the browser handles automatically) if redirected to Google for login
                        $log.info("Server responded \"" + stateData + "\" after previous problem \"" + previousState + "\"");
                        // no update
                        state = previousState;
                    }
                }
                stateData = response;
            } else {
                stateData = response.data;
                if (stateData.shuttingDown) {
                    state = BrServerStatusModalController.STATES.STOPPING;
                } else if (!stateData.up) {
                    state = BrServerStatusModalController.STATES.STARTING;
                } else if (stateData.healthy && stateData.ha.planeId && stateData.ha.masterId !== stateData.ha.ownId) {
                    state = BrServerStatusModalController.STATES.NOT_HA_MASTER;
                } else if (!stateData.healthy) {
                    state = BrServerStatusModalController.STATES.UNHEALTHY;
                }
            }
            previousState = state;
            $rootScope.$broadcast('br-server-state-update', {state: state, stateData: stateData});
            if (state !== BrServerStatusModalController.STATES.OK && !cookie.dismissed && cookie.dismissedSate !== state) {
                openModal(state, stateData);
            }
        }

        function openModal(state, stateData) {
            if (!modalInstance) {
                modalInstance = $uibModal.open({
                    animation: true,
                    template: modalTemplate,
                    backdropClass: 'server-status-index',
                    windowClass: 'server-status-index',
                    controller: BrServerStatusModalController,
                    controllerAs: 'vm',
                    size: 'md',
                    resolve: {
                        state: () => (state),
                        stateData: () => (stateData)
                    }
                });
                modalInstance.result.then((reason) => {
                    if (reason === 'understood') {
                        cookie.dismissed = true;
                        cookie.dismissedSate = state;
                        $cookies.putObject(COOKIE_KEY, cookie, {expires: getCookieExpiryDate()});
                    }
                }, () => (modalInstance = null));
            }
        }

        function getCookieExpiryDate() {
            return new Date(Date.now() + COOKIE_EXPIRY);
        }

        checkStatus();


        class BrServerStatusModalController {
            static STATES = {
                OK: 'OK',
                STARTING: 'STARTING',
                STOPPING: 'STOPPING',
                NOT_HA_MASTER: 'NOT-HA-MASTER',
                NO_CONNECTION: 'NO-CONNECTION',
                UNHEALTHY: 'UNHEALTHY',
                SESSION_INVALIDATED: 'SESSION_INVALIDATED',
                SESSION_AGE_EXCEEDED: 'SESSION_AGE_EXCEEDED',
                OTHER_ERROR: 'OTHER_ERROR',
                USER_NOT_AUTHORIZED: 'USER_NOT_AUTHORIZED'
            };
            static $inject = ['$scope', '$uibModalInstance', 'state', 'stateData'];

            constructor($scope, $uibModalInstance, state, stateData) {
                this.$uibModalInstance = $uibModalInstance;
                this.state = state;
                this.stateData = stateData;
                $scope.$on('br-server-state-update', (event, value) => {
                    this.state = value.state;
                    this.stateData = value.stateData;
                });
            }

            close(reason = 'understood') {
                this.$uibModalInstance.close(reason);
            }

            get masterUri() {
                if (this.stateData.ha.nodes.hasOwnProperty(this.stateData.ha.masterId)) {
                    return this.stateData.ha.nodes[this.stateData.ha.masterId].nodeUri;
                } else {
                    return null;
                }
            }

            get nodes() {
                let currentNodeId = this.stateData.ha.ownId;
                let masterNode = null;
                let result = [];
                for (let nodeId in this.stateData.ha.nodes) {
                    let currentNode = this.stateData.ha.nodes[nodeId];
                    if (currentNode.nodeId === this.stateData.ha.masterId) {
                        masterNode = currentNode;
                    }
                    result.push(currentNode);
                }
                return result.reduce((pre, node) => {
                    node.state = ((node.localTimestamp + 30 * 1000) < masterNode.localTimestamp) ? 'offline' : 'online';
                    node.isMasterNode = node.nodeId === masterNode.nodeId;
                    node.isCurrentNode = node.nodeId === currentNodeId;
                    pre.push(node);
                    return pre;
                }, []);
            }
        }
    }
}
