// 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, $) {
  $.extend(cloudStack, {
    home: 'dashboard',

    sectionPreFilter: function(args) {
      var sections = [];

      if(isAdmin()) {
        sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "system", "global-settings", "configuration", "projects", "regions"];
      }
      else if(isDomainAdmin()) {
        sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "domains", "events", "projects"];
      }
      else if (g_userProjectsEnabled) {
        sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "projects"];
      }
      else { //normal user
        sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events"];
      }

      if (cloudStack.plugins.length) {
        sections.push('plugins');
      }

      return sections;
    },
    sections: {
      /**
       * Dashboard
       */
      dashboard: {},      
      instances: {},
      storage: {},
      network: {},
      templates: {},
      events: {},
			projects: {},
      accounts: {},
			
      domains: {}, //domain-admin and root-admin only

      regions: {}, //root-admin only
      system: {},  //root-admin only     
      'global-settings': {}, //root-admin only     
      configuration: {}, //root-admin only
      plugins: {}
    }
  });

  $(function() {
    // Get language
    g_lang = $.cookie('lang') ? $.cookie('lang') : 'en';

    /**
     * Generic error handling
     */
		
    $.ajaxSetup({
		  url: clientApiUrl,
      async: true,
      dataType: 'json',
      cache: false,
      error: function(data) {
				var clickAction = false;
				if (isValidJsonString(data.responseText)) {
					var json = JSON.parse(data.responseText);
					if (json != null) {
						var property;
						for(property in json) {}
						var errorObj = json[property];
						if(errorObj.errorcode == 401 && errorObj.errortext == "unable to verify user credentials and/or request signature") {
							clickAction = function() {
								$('#user-options a').eq(0).trigger('click');
							};
						}
					}
				}
				cloudStack.dialog.notice({ message: parseXMLHttpResponse(data), clickAction: clickAction });
      },
			beforeSend: function(XMLHttpRequest) {
				if (g_mySession == $.cookie("JSESSIONID")) {
					return true;
				} 
				else {
					var clickAction = function() {
						$('#user-options a').eq(0).trigger('click');
					};
					cloudStack.dialog.notice({ message: _l('label.session.expired'), clickAction: clickAction });
					return false;
				}
			}	
    });

    var $container = $('#cloudStack3-container');

    var loginArgs = {
      $container: $container,

      // Use this for checking the session, to bypass login screen
      bypassLoginCheck: function(args) { //determine to show or bypass login screen
			  if (g_loginResponse == null) { //show login screen
				  /*
					but if this is a 2nd browser window (of the same domain), login screen still won't show because $.cookie('sessionKey') is valid for 2nd browser window (of the same domain) as well.
					i.e. calling listCapabilities API with g_sessionKey from $.cookie('sessionKey') will succeed, 
					then userValid will be set to true, then an user object (instead of "false") will be returned, then login screen will be bypassed.          				
					*/
					g_mySession = $.cookie('JSESSIONID');
					g_sessionKey = $.cookie('sessionKey');
					g_role = $.cookie('role');        
					g_username = $.cookie('username');
					g_userid = $.cookie('userid');
					g_account = $.cookie('account');
					g_domainid = $.cookie('domainid');
					g_userfullname = $.cookie('userfullname');		
					g_timezone = $.cookie('timezone');  
					if($.cookie('timezoneoffset') != null)
						g_timezoneoffset = isNaN($.cookie('timezoneoffset'))? null: parseFloat($.cookie('timezoneoffset'));
					else
						g_timezoneoffset = null;   
        }
				else { //single-sign-on	(bypass login screen)	
					g_mySession = $.cookie('JSESSIONID');
					g_sessionKey = encodeURIComponent(g_loginResponse.sessionkey);
					g_role = g_loginResponse.type;            
					g_username = g_loginResponse.username;
					g_userid = g_loginResponse.userid;
					g_account = g_loginResponse.account;
					g_domainid = g_loginResponse.domainid;
					g_userfullname = g_loginResponse.firstname + ' ' + g_loginResponse.lastname;
					g_timezone = g_loginResponse.timezone;										
					if(g_loginResponse.timezoneoffset != null)
						g_timezoneoffset = isNaN(g_loginResponse.timezoneoffset)? null: parseFloat(g_loginResponse.timezoneoffset);
					else
						g_timezoneoffset = null;   					
				}
								
        var userValid = false;
        $.ajax({
          url: createURL("listCapabilities"),
          dataType: "json",
          async: false,
          success: function(json) {
            g_capabilities = json.listcapabilitiesresponse.capability;
						$.cookie('capabilities', g_capabilities, { expires: 1});
						
            g_supportELB = json.listcapabilitiesresponse.capability.supportELB.toString(); //convert boolean to string if it's boolean
            $.cookie('supportELB', g_supportELB, { expires: 1});
                     
            if (json.listcapabilitiesresponse.capability.userpublictemplateenabled != null) {
              g_userPublicTemplateEnabled = json.listcapabilitiesresponse.capability.userpublictemplateenabled.toString(); //convert boolean to string if it's boolean
              $.cookie('userpublictemplateenabled', g_userPublicTemplateEnabled, { expires: 1});
            }  
						
						g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects;
            $.cookie('userProjectsEnabled', g_userProjectsEnabled, { expires: 1 });
			
            g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion;
						
            if(json.listcapabilitiesresponse.capability.apilimitinterval != null && json.listcapabilitiesresponse.capability.apilimitmax != null) {						
							var intervalLimit = ((json.listcapabilitiesresponse.capability.apilimitinterval * 1000) / json.listcapabilitiesresponse.capability.apilimitmax ) * 3; //multiply 3 to be on safe side
							//intervalLimit = 9999; //this line is for testing only, comment it before check in
							if(intervalLimit > g_queryAsyncJobResultInterval)
								g_queryAsyncJobResultInterval = intervalLimit;						
						}
						
            userValid = true;
          },
          error: function(xmlHTTP) { //override default error handling, do nothing instead of showing error "unable to verify user credentials" on login screen          
          },
          beforeSend : function(XMLHttpResponse) {					  
						return true;
					}	
        });

        if (userValid && isAdmin()) {
          $.ajax({
            url: createURL("listSwifts"),
            dataType: "json",
            async: false,
            success: function(json) {
              var items = json.listswiftsresponse.swift;
              if(items != null && items.length > 0)
                havingSwift = true;
            }
          });
          if (havingSwift == false) {
            $.ajax({
              url: createURL("listS3s"),
              dataType: "json",
              async: false,
              success: function(json) {
                var items = json.lists3sresponse.s3;
                if (items != null && items.length > 0) {
                  havingS3 = true;
                }
              }
            });
          }
        } else {
          havingSwift = false;
          havingS3 = false;
        }

        return userValid ? {
          user: {
            userid: g_userid,
            username: g_username,
            account: g_account,
            name: g_userfullname,
            role: g_role,            
            domainid: g_domainid
          }
        } : false;

        return testAddUser;
      },

      // Actual login process, via form
      loginAction: function(args) {
        var array1 = [];
        array1.push("&username=" + encodeURIComponent(args.data.username));

        var password;
        if (md5HashedLogin)
          password = $.md5(args.data.password);
        else
          password = todb(args.data.password);
        array1.push("&password=" + password);

        var domain;
        if(args.data.domain != null && args.data.domain.length > 0) {
          if (args.data.domain.charAt(0) != "/")
            domain = "/" + args.data.domain;
          else
            domain = args.data.domain;
          array1.push("&domain=" + encodeURIComponent(domain));
        }
        else {
          array1.push("&domain=" + encodeURIComponent("/"));
        }
				
        var loginCmdText = array1.join("");			
				
        $.ajax({
          type: "POST",
          data: "command=login" + loginCmdText + "&response=json",					
          dataType: "json",
          async: false,
          success: function(json) {			
            var loginresponse = json.loginresponse;

            g_mySession = $.cookie('JSESSIONID');
            g_sessionKey = encodeURIComponent(loginresponse.sessionkey);
            g_role = loginresponse.type;            
            g_username = loginresponse.username;
            g_userid = loginresponse.userid;
            g_account = loginresponse.account;
            g_domainid = loginresponse.domainid;
            g_timezone = loginresponse.timezone;
            g_timezoneoffset = loginresponse.timezoneoffset;
            g_userfullname = loginresponse.firstname + ' ' + loginresponse.lastname;

            $.cookie('sessionKey', g_sessionKey, { expires: 1});
            $.cookie('username', g_username, { expires: 1});
            $.cookie('account', g_account, { expires: 1});
            $.cookie('domainid', g_domainid, { expires: 1});
            $.cookie('role', g_role, { expires: 1});            
            $.cookie('timezoneoffset', g_timezoneoffset, { expires: 1});
            $.cookie('timezone', g_timezone, { expires: 1});
            $.cookie('userfullname', g_userfullname, { expires: 1 });
            $.cookie('userid', g_userid, { expires: 1 });

            $.ajax({
              url: createURL("listCapabilities"),              
              dataType: "json",
              async: false,
              success: function(json) {
                g_capabilities = json.listcapabilitiesresponse.capability;
								$.cookie('capabilities', g_capabilities, { expires: 1});
								
                g_supportELB = json.listcapabilitiesresponse.capability.supportELB.toString(); //convert boolean to string if it's boolean
                $.cookie('supportELB', g_supportELB, { expires: 1});

                if (json.listcapabilitiesresponse.capability.userpublictemplateenabled != null) {
                  g_userPublicTemplateEnabled = json.listcapabilitiesresponse.capability.userpublictemplateenabled.toString(); //convert boolean to string if it's boolean
                  $.cookie('userpublictemplateenabled', g_userPublicTemplateEnabled, { expires: 1});
                }

                g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects;
                $.cookie('userProjectsEnabled', g_userProjectsEnabled, { expires: 1 });
				
                g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion;
								
								if(json.listcapabilitiesresponse.capability.apilimitinterval != null && json.listcapabilitiesresponse.capability.apilimitmax != null) {
									var intervalLimit = ((json.listcapabilitiesresponse.capability.apilimitinterval * 1000) / json.listcapabilitiesresponse.capability.apilimitmax ) * 3; //multiply 3 to be on safe side
									//intervalLimit = 8888; //this line is for testing only, comment it before check in
									if(intervalLimit > g_queryAsyncJobResultInterval)
										g_queryAsyncJobResultInterval = intervalLimit;		
								}
								
                args.response.success({
                  data: {
                    user: $.extend(true, {}, loginresponse, {
                      name: loginresponse.firstname + ' ' + loginresponse.lastname,
                      role: loginresponse.type == 1 ? 'admin' : 'user',
                      type: loginresponse.type
                    })
                  }
                });
              },
              error: function(xmlHTTP) {
                args.response.error();
              }				
            });

            if (isAdmin()) {
              $.ajax({
                url: createURL("listSwifts"),
                dataType: "json",
                async: false,
                success: function(json) {
                  var items = json.listswiftsresponse.swift;
                  if(items != null && items.length > 0)
                    havingSwift = true;
                }
              });
              if (havingSwift = false) {
                $.ajax({
                  url: createURL("listS3s"),
                  dataType: "json",
                  async: false,
                  success: function(json) {
                    var items = json.lists3sresponse.s3;
                    if (items != null && items.length > 0) {
                      havingS3 = true;
                    }
                  }
                });
              }
            } else {
              havingSwift = false;
              havingS3 = false;
            }

            // Get project configuration
            // TEMPORARY -- replace w/ output of capability response, etc., once implemented
            window.g_projectsInviteRequired = false;
          },
          error: function(XMLHttpRequest) {					  
						var errorMsg = parseXMLHttpResponse(XMLHttpRequest);							
            if(errorMsg.length == 0 && XMLHttpRequest.status == 0) 		
						  errorMsg = dictionary['error.unable.to.reach.management.server'];	 
            else 
              errorMsg = _l('error.invalid.username.password'); //override error message             						
            args.response.error(errorMsg);			
          },										
					beforeSend : function(XMLHttpResponse) {				
						return true;
					}	
        });
      },

      logoutAction: function(args) {
        $.ajax({
          url: createURL('logout'),
          async: false,
          success: function() {					  
						g_mySession = null;
						g_sessionKey = null;
						g_username = null;	
						g_account = null;
						g_domainid = null;	
						g_timezoneoffset = null;
						g_timezone = null;
						g_supportELB = null;						
						g_loginCmdText = null;
						window.name = '';
						
						$.cookie('JSESSIONID', null);
						$.cookie('sessionKey', null);
						$.cookie('username', null);
						$.cookie('account', null);
						$.cookie('domainid', null);
						$.cookie('role', null);
						$.cookie('networktype', null); 
						$.cookie('timezoneoffset', null);
						$.cookie('timezone', null);
						$.cookie('supportELB', null);
																	
						if(onLogoutCallback()) {	 //onLogoutCallback() will set g_loginResponse(single-sign-on variable) to null, then bypassLoginCheck() will show login screen.
              document.location.reload(); //when onLogoutCallback() returns true, reload the current document.
						}
          },
          error: function() {
					  if(onLogoutCallback()) {	 //onLogoutCallback() will set g_loginResponse(single-sign-on variable) to null, then bypassLoginCheck() will show login screen.
              document.location.reload(); //when onLogoutCallback() returns true, reload the current document.
						}            
          },			
					beforeSend : function(XMLHttpResponse) {
						return true;
					}							
        });
      },

      // Show cloudStack main UI widget
      complete: function(args) {
        var context = {
          users: [args.user]
        };
        var cloudStackArgs = $.extend(cloudStack, {
          context: context
        });

        // Check to invoke install wizard
        cloudStack.installWizard.check({
          context: context,
          response: {
            success: function(args) {
              if (args.doInstall && isAdmin()) {
                var initInstallWizard = function() {
                  cloudStack.uiCustom.installWizard({
                    $container: $container,
                    context: context,
                    complete: function() {
                      // Show cloudStack main UI
                      $container.cloudStack($.extend(cloudStackArgs, { hasLogo: false }));
                    }
                  });
                };

                initInstallWizard();
              } else {
                // Show cloudStack main UI
                $container.cloudStack($.extend(cloudStackArgs, { hasLogo: false }));
              }
            }
          }
        });

        // Logout action
        $('#user-options a').live('click', function() {
          loginArgs.logoutAction({
            context: cloudStack.context
          });
        });

        window._reloadUI = function() {
          $('#container').html('');
          $('#container').cloudStack(window.cloudStack);
        };
      }
    };
		
    document.title = 'CloudStack';

    if ($.urlParam('loginUrl') != 0
		||(window.name != null && window.name.indexOf("&domain=") != -1)) {
      // SSO
      loginArgs.hideLoginScreen = true;
    }
    
    cloudStack.uiCustom.login(loginArgs);

    // Localization
    cloudStack.localizationFn = function(str) {
      return dictionary[str];
    };
  });
})(cloudStack, jQuery);
