/*
 * 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 map from "lodash/map";
import {HIDE_INTERSTITIAL_SPINNER_EVENT} from 'brooklyn-ui-utils/interstitial-spinner/interstitial-spinner';
import template from "./summary.template.html";

export const summaryState = {
    name: 'main.inspect.summary',
    url: '/summary',
    template: template,
    controller: ['$scope', '$state', '$stateParams', '$q', '$http', 'brSnackbar', 'entityApi', 'locationApi', summaryController],
    controllerAs: 'vm'
};

export function summaryController($scope, $state, $stateParams, $q, $http, brSnackbar, entityApi, locationApi) {
    $scope.$emit(HIDE_INTERSTITIAL_SPINNER_EVENT);

    const {
        applicationId,
        entityId
    } = $stateParams;

    this.error = {};

    let vm = this;
    vm.activitiesInError = [];
    vm.sensorsToShow = {
        'service.state': 'Service status',
        'service.isUp': 'Service up',
        'service.problems': 'Service problem',
        'service.notUp.indicators': 'Service indicator'
    };

    let observers = [];

    entityApi.entity(applicationId, entityId).then((response)=> {
        vm.entity = response.data;
        vm.name = response.data.name;
        vm.error.entity = undefined;
        observers.push(response.subscribe((response)=> {
            vm.entity = response.data;
            vm.name = response.data.name;
            vm.error.entity = undefined;
        }));
    }).catch((error)=> {
        vm.error.entity = 'Cannot load entity with ID: ' + entityId;
    });

    entityApi.entityConfigState(applicationId, entityId).then((response)=> {
        vm.config = response.data;
        vm.error.config = undefined;
        observers.push(response.subscribe((response)=> {
            vm.config = response.data;
            vm.error.config = undefined;
        }));
    }).catch((error)=> {
        vm.error.config = 'Cannot load configuration for entity with ID: ' + entityId;
    });

    entityApi.entityConfigInfo(applicationId, entityId).then((response)=> {
        vm.configInfo = response.data;
        vm.error.config = undefined;
        observers.push(response.subscribe((response)=> {
            vm.configInfo = response.data;
            vm.error.config = undefined;
        }));
    }).catch((error)=> {
        vm.error.config = 'Cannot load configuration information for entity with ID: ' + entityId;
    });

    entityApi.entitySpec(applicationId, entityId).then((response)=> {
        vm.spec = response.data;
        vm.error.spec = undefined;
        observers.push(response.subscribe((response)=> {
            vm.spec = response.data;
            vm.error.spec = undefined;
        }));
    }).catch((error)=> {
        vm.error.spec = 'Cannot load spec for entity with ID: ' + entityId;
    });

    entityApi.entityActivities(applicationId, entityId).then((response)=> {
        vm.activities = parseActivitiesResponse(response.data);
        vm.error.activities = undefined;
        observers.push(response.subscribe((response)=> {
            vm.activities = parseActivitiesResponse(response.data);
            vm.error.activities = undefined;
        }));
    }).catch((error)=> {
        vm.error.spec = 'Cannot load spec for entity with ID: ' + entityId;
    });

    entityApi.entitySensorsState(applicationId, entityId).then((response)=> {
        vm.sensors = response.data;
        vm.error.sensors = undefined;
        observers.push(response.subscribe((response)=> {
            vm.sensors = response.data;
            vm.error.sensors = undefined;
        }));
    }).catch((error)=> {
        vm.error.sensors = 'Cannot sensors for entity with ID: ' + entityId;
    });

    entityApi.entitySensorsInfo(applicationId, entityId).then((response)=> {
        vm.sensorsInfo = response.data;
        vm.error.sensors = undefined;
        observers.push(response.subscribe((response)=> {
            vm.sensorsInfo = response.data;
            vm.error.sensors = undefined;
        }));
    }).catch((error)=> {
        vm.error.sensors = 'Cannot sensors information for entity with ID: ' + entityId;
    });

    entityApi.entityPolicies(applicationId, entityId).then((response)=> {
        // vm.policies = response.data;
        // TODO: Replace once the new adjunct endpoint has been merged
        vm.policies = response.data.map(policy => {
            policy.type = 'policy';
            return policy;
        });
        vm.error.policies = undefined;
        observers.push(response.subscribe((response)=> {
            // vm.policies = response.data;
            // TODO: Replace once the new adjunct endpoint has been merged
            vm.policies = response.data.map(policy => {
                policy.type = 'policy';
                return policy;
            });
            vm.error.policies = undefined;
        }));
    }).catch((error)=> {
        vm.error.policies = 'Cannot load policies for entity with ID: ' + entityId;
    });

    $http.get('/v1/ui-metadata-registry', {params: {type: 'location'}}).then(response => {
        vm.metadata = response.data;
    });

    entityApi.entityLocations(applicationId, entityId).then(response => {
        parseLocationsResponse(response.data);
        observers.push(response.subscribe(response => {
            parseLocationsResponse(response.data);
        }));
    }).catch(error => {
        vm.error.location = 'Cannot load location for entity with ID: ' + entityId;
    });

    $scope.$on('$destroy', ()=> {
        observers.forEach((observer)=> {
            observer.unsubscribe();
        });
    });

    this.isObject = function(item) {
        return angular.isObject(item);
    };

    this.isEmpty = function(item) {
        if (angular.isObject(item)) {
            return Object.keys(item).length === 0;
        } else if (angular.isString(item)) {
            return item.length === 0;
        } else {
            return item === undefined || item === null;
        }
    };

    this.updateEntityName = function() {
        if (vm.name && vm.name !== vm.entity.name) {
            entityApi.updateEntityName(applicationId, entityId, this.name).then((response)=> {
                vm.entity.name = vm.name;
            }).catch((error)=> {
                let errorMessage= ('undefined' === typeof error.message)? error.error.message: error.message;
                brSnackbar.create('Cannot update entity name: ' + errorMessage);
                vm.name = vm.entity.name;
            });
        }
    };

    this.expandMultiLocation = () => {
        if (!vm.subLocations) {
            vm.subLocations = {
                requested: false
            };
        }

        if (!vm.subLocations.requested) {
            vm.subLocations.requested = true;
            $q.all(vm.location.multi.config.subLocations.map(subLocation => locationApi.location(subLocation.id))).then(responses => {
                vm.subLocations.items = responses.map(response => response.data);
            }).catch(error => {
                vm.error.subLocations = 'Cannot load sub-locations for entity with ID: ' + entityId;
            })
        }
    };

    function parseActivitiesResponse(data) {
        if (data) {

            let activities = angular.copy(vm.activitiesInError);

            map(data, (activityObject) => {
                if (activityObject.isError) {
                    let index = activities.findIndex(function (activity) {
                        return activity.displayName === activityObject.displayName;
                    });
                    if (index === -1) {
                        activities.push(activityObject);
                    }
                    else {
                        activities[index] = activityObject;
                    }
                }
            });

            vm.activitiesInError = activities.sort(function (a, b) {
                if (a.endTimeUtc > b.endTimeUtc) {
                    return 1;
                }
                if (a.endTimeUtc < b.endTimeUtc) {
                    return -1;
                }
                return a.displayName > b.displayName;
            }).reverse();

            vm.mostRecentActivityInError = vm.activitiesInError.length > 0 ? vm.activitiesInError[vm.activitiesInError.length - 1] : undefined;
        }
    }

    function parseLocationsResponse(data) {
        $q.all(data.map(location => locationApi.location(location.id))).then(responses => {
            vm.location = {
                items: responses.filter(item => item.data.config['spec.final'] !== 'multi').map(response => response.data)
            };

            let multi = responses.find(item => item.data.config['spec.final'] === 'multi');
            if (multi) {
                vm.location.multi = multi.data;
            }

            vm.error.location = undefined;
        }).catch(error => {
            vm.error.location = 'Cannot load location for entity with ID: ' + entityId;
        });
    }
}

export function specToLabelFilter() {
    return function(input, map) {
        if (map && map instanceof Object) {
            return map.hasOwnProperty(input) ? map[input].name : input;
        }
        return input;
    }
}
