/*
 * 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;

        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) {
                console.log(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 {
                    state = BrServerStatusModalController.STATES.OTHER_ERROR;
                }

                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;
                }
            }
            $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;
                }, []);
            }
        }
    }
}
