/*
 *  Copyright 2015 Anyware Services
 *
 *  Licensed 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.
 */

/**
 * Singleton class defining the actions related to the plugins and workpaces tools
 * @private
 */
Ext.define('Ametys.plugins.web.site.SiteActions', {
	singleton: true,
	
	/**
	 * @private
	 * @property {Ametys.window.DialogBox} _box The dialog box for creating a new site
	 */
	
	/**
	 * Create a new site
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	add: function(controller)
	{
		var target = controller.getMatchingTargets()[0];
		if (target != null)
		{
			var parentId = target.getId() == Ametys.message.MessageTarget.SITE ? target.getParameters().id : null;
			Ametys.plugins.web.site.CreateSite.act(parentId, Ext.bind(this._addCb, this));
		}
	},
	
	/**
	 * @private
	 * Callback function called after creating a site
	 * @param {String} id The site id
	 * @param {String} name The site name
	 * @param {String} parentId The site parent id. Can be null
	 */
	_addCb: function (id, name, parentId)
	{
		Ext.create('Ametys.message.Message', {
			type: Ametys.message.Message.CREATED,
			targets: [{
				id: Ametys.message.MessageTarget.SITE,
				parameters: {
					id: id,
					name: name,
					parentId: parentId
				}
			}]
		});
        
        // Enable to choose users populations allowed to connect to the application for this site
        var contextBO = '/sites/' + name;
        var contextFO = '/sites-fo/' + name;
        Ametys.plugins.web.populations.PopulationActions.openLinkToSiteDialog(contextBO, contextFO, name, name);
		
		// Open configuration tool
		Ametys.tool.ToolsManager.openTool('uitool-admin-site-config', {id: name, siteId: id, siteName: name});
	},
	
	/**
	 * Delete a site
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	remove: function(controller)
	{
		var target = controller.getMatchingTargets()[0];
		if (target != null)
		{
			Ametys.Msg.confirm("{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_DELETE_LABEL}}", 
					"{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_DELETE_WARNING}}", 
					Ext.bind(this._confirmDelete, this, [target.getParameters().id, target.getParameters().name], 1), 
					this
			);
		}
	},
	
	/**
	 * @private
	 * The callback function invoked after the confirm box for delete process is closed
	 * @param {String} answer The ID of the button pressed
	 * @param {String} id the site id
	 * @param {String} name the site name
	 */
	_confirmDelete: function (answer, id, name)
	{
		if (answer == 'yes')
		{
			Ametys.web.site.SiteDAO.deleteSite([ id, name ], null, {});
		}
	},
	
	/**
	 * Configure a site
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	configure: function(controller)
	{
		var target = controller.getMatchingTargets()[0];
		if (target != null)
		{
			Ametys.tool.ToolsManager.openTool('uitool-admin-site-config', {id: target.getParameters().name, siteName: target.getParameters().name, siteId: target.getParameters().id, siteTitle: target.getParameters().title});
		}
	},
	
	/**
	 * Open a site
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	open: function(controller)
	{
		var target = controller.getMatchingTargets()[0];
		if (target != null)
		{
			Ametys.openWindow(Ametys.CONTEXT_PATH + '/' + target.getParameters().name + '/' + 'index.html');
		}
	},
	
	/**
	 * Clear cache of a site
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	clearCache: function(controller)
	{
		var target = controller.getMatchingTargets()[0];
		if (target != null)
		{
			Ametys.Msg.confirm("{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHE_CONFIRM_TITLE}}",
					"{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHE_CONFIRM_DESC}}",
					Ext.bind(this._confirmClearCache, this, [target.getParameters().id, target.getParameters().name], 1),
					this
			);
		}
	},
	
	/**
	 * @private
	 * The callback function invoked after the confirm box for clearing cache is closed
	 * @param {String} answer The ID of the button pressed
	 * @param {String} id the site id
	 * @param {String} name the site name
	 */
	_confirmClearCache: function (answer, id, name)
	{
		if (answer == 'yes')
		{
			Ametys.data.ServerComm.callMethod({
				role: "org.ametys.web.repository.site.SiteDAO",
				methodName: "clearCache",
				parameters: [name],
				callback: {
					scope: this,
					handler: this._clearCacheCb,
					arguments: {name: name}
				},
				errorMessage: {
					category: this.self.getName(),
					msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHE_ERROR}}"
				},
				waitMessage: true
			});
		}
	},
	
	/**
	 * @private
	 * Callback function after clearing site's cache
	 * @param {Object} response The server response
	 * @param {Object} args The callback arguments
	 */
	_clearCacheCb: function (response, args)
	{
        Ametys.notify({
            type: 'info',
            iconGlyph: 'ametysicon-garbage11',
            title: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHE_OK_TITLE}} (" + args.name + ")",
            description: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHE_OK_DESC}}"
        });
	},
	
	/**
	 * Clear cache of all sites
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	clearAllCache: function(controller)
	{
		Ametys.Msg.confirm("{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHEALL_CONFIRM_TITLE}}",
				"{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHEALL_CONFIRM_DESC}}",
				Ext.bind(this._confirmClearAllCache, this),
				this
		);
	},
	
	/**
	 * @private
	 * The callback function invoked after the confirm box for clearing all caches is closed
	 * @param {String} answer The ID of the button pressed
	 */
	_confirmClearAllCache: function (answer)
	{
		if (answer == 'yes')
		{
			Ametys.data.ServerComm.callMethod({
				role: "org.ametys.web.repository.site.SiteDAO",
				methodName: "clearAllCaches",
				parameters: [],
				callback: {
					scope: this,
					handler: this._clearAllCacheCb
				},
				errorMessage: {
					category: this.self.getName(),
					msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHEALL_ERROR}}"
				},
				waitMessage: true
			});
		}
	},
	
	/**
	 * @private
	 * Callback function after clearing all caches
	 * @param {String[]} result The server response
	 * @param {Object} args The callback arguments
	 */
	_clearAllCacheCb: function (result, args)
	{
        let errors = result.errors;
		if (errors.length > 0)
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHEALL_OK_TITLE}}",
				msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHEALL_SITES_ERROR}}" + errors.join(', ') + "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHEALL_SITES_ERROR_2}}",
				buttons: Ext.Msg.OK,
				icon: Ext.MessageBox.ERROR
			});
			return;
		}
		else
		{
            Ametys.notify({
                type: 'info',
                iconGlyph: 'ametysicon-garbage11',
                title: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHEALL_OK_TITLE}}",
                description: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHEALL_OK_DESC}} " + result.count +  " {{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHEALL_OK_DESC2}} " + result.front +  " {{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_HANDLE_CLEARCACHEALL_OK_DESC3}}"
            });
		}
	},
	
	/**
	 * Open the site's statistics
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	statistics: function (controller)
	{
		var target = controller.getMatchingTargets()[0];
		if (target != null)
		{
 			Ametys.tool.ToolsManager.openTool('uitool-admin-site-statistics', {id: target.getParameters().name, siteName: target.getParameters().name, siteTitle: target.getParameters().title});
		}
	},
	
	/**
	 * Open the selected site's back cache statistics
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	cacheStatisticsBack: function(controller)
	{
		var target = controller.getMatchingTargets()[0];
		if (target != null)
		{
 			Ametys.tool.ToolsManager.openTool('uitool-admin-cache-statistics-back', {id: target.getParameters().name, siteName: target.getParameters().name, siteTitle: target.getParameters().title});
		}
	},

	/**
	 * Open the selected site's serverss statistics for the servers
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	cacheStatisticsServers: function(controller)
	{
		var target = controller.getMatchingTargets()[0];
		if (target != null)
		{
 			Ametys.tool.ToolsManager.openTool('uitool-admin-cache-statistics-servers', {id: target.getParameters().name, siteName: target.getParameters().name, siteTitle: target.getParameters().title});
		}
	},
	
	/**
	 * Leave the site configuration without saving
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	unsaveConfig: function (controller)
	{
		var tool = Ametys.tool.ToolsManager.getFocusedTool();
		
		Ametys.Msg.confirm("{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_UNSAVE_CONFIG_CONFIRM_TITLE}}",
				"{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_UNSAVE_CONFIG_CONFIRM_DESC}}",
				Ext.bind(this._unsaveConfirm, this, [tool], 1),
				this
		);
	},
	
	/**
	 * @private
	 * The callback function invoked after the confirm box for leaving configuration
	 * @param {String} answer The ID of the button pressed
     * @param {Ametys.tool.Tool} tool The tool
	 */
	_unsaveConfirm: function (answer, tool)
	{
		if (answer == 'yes')
		{
			tool.close();
		}
	},
	
	/**
	 * Save the site configuration
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	saveConfig: function (controller)
	{
		var form = Ametys.form.SaveHelper.getForm(controller.getMatchingTargets());
		if (form != null)
		{
			var tool = Ametys.tool.ToolsManager.getFocusedTool();
			var target = controller.getMatchingTargets()[0];
			var siteName = target.getParameters().name;
			var siteId = target.getParameters().id;
			
			Ametys.form.SaveHelper.canSave(form, Ext.bind(this._doSave, this, [tool, form, siteName, siteId], 1));
		}
	},
	
	/**
	 * @private
	 * Save the site configuration
	 * @param {Boolean} canSave True if the configuration can be saved
	 * @param {Ametys.tool.Tool} tool The content tool
	 * @param {Ametys.form.ConfigurableFormPanel} form The form panel
	 * @param {String} siteName The site name
	 * @param {String} siteId The site ID
 	 */
	_doSave: function (canSave, tool, form, siteName, siteId)
	{
		Ametys.data.ServerComm.callMethod({
			role: "org.ametys.web.repository.site.SiteDAO",
			methodName: "configureSite",
			parameters: [siteName, form.getJsonValues()],
			callback: {
				scope: this,
				handler: this._saveCb,
				arguments: {
					form: form,
					tool: tool,
					id: siteId,
					name: siteName
				}
			},
			errorMessage: {
				category: this.self.getName(),
				msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_ERROR}}"
			},
			waitMessage: {
				target: tool.getContentPanel(),
				msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_SAVING}}"
			}
		});
	},
	
	/**
	 * Callback function called after #_doSave is processed.
	 * Fires {@link Ametys.message.Message#MODIFIED} message for edited site
	 * @param {Object} response The XML response provided by the {@link Ametys.data.ServerComm}
	 * @param {Object} params The callback parameters passed to the {@link Ametys.data.ServerComm#send} method :
	 * @param {Ametys.form.ConfigurableFormPanel} params.form The form panel
	 * @private
	 */
	_saveCb: function (response, params)
	{
		var fieldsInError = {};
		// Handle form errors
		var errors = response.errors || [];
		if (errors.length > 0)
		{
			for (var i=0; i < errors.length; i++)
			{
				var fdName = errors[i].name;
				var errorMsg = errors[i].errorMessages.join("<br/>");
				
				fieldsInError[fdName] = errorMsg;
			}
		}
		
		if (errors.length > 0 && params.form)
		{
			var msg = "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_FAILED_DESC}}";
			msg += errors.length  == 1 ? "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_FAILED_DESC_SINGLE}}" : errors.length + "{{i18n PLUGINS_WEB_ADMINISTRATOR_SITES_SAVE_CONFIG_FAILED_DESC_MULTI}}";
			Ametys.form.SaveHelper.handleServerErrors(params.form, null, msg, fieldsInError);
			return;
		}
		
		// Close tool
		params.tool.close();
		
		Ext.create('Ametys.message.Message', {
			type: Ametys.message.Message.MODIFIED,
			targets: [{
				id: Ametys.message.MessageTarget.SITE,
				parameters: {
					name: params.name,
					id: params.id
				}
			}]
		});
	}
	
});