// 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.
(function($, cloudStack) {
    // Admin dashboard
    cloudStack.sections.dashboard = {
        title: 'label.menu.dashboard',
        show: cloudStack.uiCustom.dashboard,

        adminCheck: function(args) {
            return isAdmin() ? true : false;
        },

        // User dashboard
        user: {
            dataProvider: function(args) {
                var dataFns = {
                    instances: function(data) {                        
                    	var totalInstanceCount = 0;
                    	$.ajax({
                            url: createURL("listVirtualMachines"),
                            data: {
                                listAll: true,
                                page: 1,
                                pageSize: 1
                            },
                            async: false,
                            success: function(json) {                            	
                            	if (json.listvirtualmachinesresponse.count != undefined) {
                            		totalInstanceCount = json.listvirtualmachinesresponse.count;
                            	}   
                            }
                        });
                    	
                    	var RunningInstanceCount = 0;
                    	$.ajax({
                            url: createURL("listVirtualMachines"),
                            data: {
                                listAll: true,
                                page: 1,
                                pageSize: 1,
                                state: "Running"
                            },
                            async: false,
                            success: function(json) {                            	
                            	if (json.listvirtualmachinesresponse.count != undefined) {
                            		RunningInstanceCount = json.listvirtualmachinesresponse.count;
                            	}                                 	
                            }
                        });
                    	
                    	var stoppedInstanceCount = 0;
                    	$.ajax({
                            url: createURL("listVirtualMachines"),
                            data: {
                                listAll: true,
                                page: 1,
                                pageSize: 1,
                                state: "Stopped"
                            },
                            async: false,
                            success: function(json) {                            	
                            	if (json.listvirtualmachinesresponse.count != undefined) {
                            		stoppedInstanceCount = json.listvirtualmachinesresponse.count;
                            	}                                  	
                            }
                        });
                    	
                        dataFns.account($.extend(data, {
                            runningInstances: RunningInstanceCount,
                            stoppedInstances: stoppedInstanceCount,
                            totalInstances: totalInstanceCount
                        }));                        
                    },

                    account: function(data) {
                        var user = cloudStack.context.users[0];
                        dataFns.events($.extend(data, {
                            accountID: user.userid,
                            accountName: user.account,
                            userName: user.username,
                            accountType: user.role,
                            accountDomainID: user.domainid
                        }));
                    },

                    events: function(data) {
                        $.ajax({
                            url: createURL('listEvents'),
                            data: {
                                listAll: true,
                                page: 1,
                                pageSize: (pageSize > 4? 4: pageSize) //if default.page.size > 4, show 4 items only (since space on dashboard is limited) 
                                //pageSize: 1 //for testing only
                            },
                            success: function(json) {
                                dataFns.ipAddresses($.extend(data, {
                                    events: json.listeventsresponse.event ? json.listeventsresponse.event : []
                                }));
                            }
                        });
                    },

                    ipAddresses: function(data) {
                        $.ajax({
                            url: createURL('listNetworks'),
                            data: {
                                listAll: true,
                                page: 1,
                                pageSize: 1,
                                type: 'isolated',
                                supportedServices: 'SourceNat'
                            },
                            success: function(json) {
                                var netTotal = json.listnetworksresponse.count ?
                                    json.listnetworksresponse.count : 0;

                                $.ajax({
                                    url: createURL('listPublicIpAddresses'),
                                    data: {
                                    	page: 1,
                                        pageSize: 1
                                    },
                                    success: function(json) {
                                        var ipTotal = json.listpublicipaddressesresponse.count ?
                                            json.listpublicipaddressesresponse.count : 0;

                                        complete($.extend(data, {
                                            netTotal: netTotal,
                                            ipTotal: ipTotal
                                        }));
                                    }
                                });
                            }
                        });
                    }
                };

                var complete = function(data) {
                    args.response.success({
                        data: data
                    });
                };

                dataFns.instances({});
            }
        },

        // Admin dashboard
        admin: {
            zoneDetailView: {
                tabs: {
                    resources: {
                        title: 'label.resources',
                        custom: cloudStack.uiCustom.systemChart('resources')
                    }
                }
            },

            dataProvider: function(args) {
                var dataFns = {
                    zones: function(data) {
                        $.ajax({
                            url: createURL('listZones'),
                            success: function(json) {
                                dataFns.capacity({
                                    zones: json.listzonesresponse.zone
                                });
                            }
                        });
                    },
                    capacity: function(data) {
                        if (window.fetchLatestflag == 1) {
                            data.fetchLastest = true;
                        } else {
                            data.fetchLastest = false;
                        }
                        window.fetchLatestflag = 0;
                        dataFns.alerts(data);
                    },

                    alerts: function(data) {
                        $.ajax({
                            url: createURL('listAlerts'),
                            data: {
                                page: 1,
                                pageSize: (pageSize > 4? 4: pageSize) //if default.page.size > 4, show 4 items only (since space on dashboard is limited) 
                            },
                            success: function(json) {
                                var alerts = json.listalertsresponse.alert ?
                                    json.listalertsresponse.alert : [];

                                dataFns.hostAlerts($.extend(data, {
                                    alerts: $.map(alerts, function(alert) {
                                        return {
                                            name: cloudStack.converters.toAlertType(alert.type),
                                            description: alert.description,
                                            sent: cloudStack.converters.toLocalDate(alert.sent)
                                        };
                                    })
                                }));
                            }
                        });
                    },

                    hostAlerts: function(data) {
                        $.ajax({
                            url: createURL('listHosts'),
                            data: {
                                state: 'Alert',
                                page: 1,
                                pageSize: (pageSize > 4? 4: pageSize) //if default.page.size > 4, show 4 items only (since space on dashboard is limited) 
                            },
                            success: function(json) {
                                var hosts = json.listhostsresponse.host ?
                                    json.listhostsresponse.host : [];

                                dataFns.zoneCapacity($.extend(data, {
                                    hostAlerts: $.map(hosts, function(host) {
                                        return {
                                            name: host.name,
                                            description: 'message.alert.state.detected'
                                        };
                                    })
                                }));
                            }
                        });
                    },

                    zoneCapacity: function(data) {
                        $.ajax({
                            url: createURL('listCapacity'),
                            data: {
                                fetchLatest: data.fetchLatest,
                                sortBy: 'usage',
                                page: 0,
                                pageSize: (pageSize > 8? 8: pageSize) 
                            },
                            success: function(json) {
                                var capacities = json.listcapacityresponse.capacity ?
                                    json.listcapacityresponse.capacity : [];

                                complete($.extend(data, {
                                    zoneCapacities: $.map(capacities, function(capacity) {
                                        if (capacity.podname) {
                                            capacity.zonename = capacity.zonename.concat(', ' + _l('label.pod') + ': ' + capacity.podname);
                                        }

                                        if (capacity.clustername) {
                                            capacity.zonename = capacity.zonename.concat(', ' + _l('label.cluster') + ': ' + capacity.clustername);
                                        }

                                        capacity.zonename.replace('Zone:', _l('label.zone') + ':');

                                        return {
                                            zoneID: capacity.zoneid, // Temporary fix for dashboard
                                            zoneName: capacity.zonename,
                                            type: cloudStack.converters.toCapacityCountType(capacity.type),
                                            percent: parseInt(capacity.percentused),
                                            used: cloudStack.converters.convertByType(capacity.type, capacity.capacityused),
                                            total: cloudStack.converters.convertByType(capacity.type, capacity.capacitytotal)
                                        };
                                    })
                                }));
                            }
                        });
                    }
                };

                var complete = function(data) {
                    args.response.success({
                        data: data
                    });
                };

                dataFns.zones({});
            }
        }
    };
})(jQuery, cloudStack);
