/*
 * 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', controller]
    };

    function controller($rootScope, $scope, $http, $cookies, $interval, $uibModal) {
        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
                        console.log("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;
                }, []);
            }
        }
    }
}
