/*
 *  Copyright 2017 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.
 */

/**
 * Define general actions for authentication token
 * @private
 */
Ext.define('Ametys.plugins.core.authentication.AuthenticationTokenActions', {
	singleton: true,
	
	/**
	 * This method will open a dialog box to see the user's authentication token and generate tokens
	 */
	showTokens: function ()
	{
		if (!this._delayedInitializeAuthenticationTokenDialog())
		{
			return;
		}
		
		this._authenticationTokenStore.load();
		this._authenticationTokenBox.show();
	},
	
	/**
	 * @private
	 * Draw the authentication token dialog box
	 */
	_delayedInitializeAuthenticationTokenDialog: function ()
	{
		if (this._authenticationTokenDialogInitialized)
		{
			return true;
		}
		
		this._gridPanel = this._createGridPanel();
		
		this._generateTokenButton = Ext.create('Ext.button.Button', {
			text: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_BTN_LABEL}}",
			handler: this._openGenerateTokenBox,
			scope: this
		});
		
		this._authenticationTokenBox = Ext.create('Ametys.window.DialogBox', {
			title :"{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_LABEL}}",
			iconCls : 'ametysicon-key162',
			
			width : 600,
			scrollable: true,
			
			items : [{
		                xtype: 'component',
		                html: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_HINT}}",
		                cls: 'a-text'
		            }, 
					this._gridPanel,
					this._generateTokenButton
				],
			
			closeAction: 'hide',
			defaultFocus: this._gridPanel,
			
			referenceHolder: true,
			defaultButton: 'validate',
			
			buttons : [ {
				reference: 'validate',
				text :"{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_BTN_OK}}",
				handler : function () { this._authenticationTokenBox.close()},
				scope: this
			} ]
		});
		
		this._authenticationTokenDialogInitialized = true;
		return true;
	},
	
	/**
	 * @private 
	 * Get the grid panel to show all user authentication token
	 * @return {Ext.Panel} The grid panel
	 */
	_createGridPanel: function ()
	{
		this._authenticationTokenStore = Ext.create('Ext.data.Store', {
            model: 'Ametys.plugins.core.authentication.AuthenticationTokenActions.Token',
            
            proxy: {
                type: 'ametys',
                plugin: 'core',
                url: 'tokens.json',
                reader: {
                    type: 'json',
                    rootProperty: 'tokens'
                }
            }
        });
		
		return Ext.create('Ext.grid.Panel', {
            cls: 'authentication-token-panel',
            store : this._authenticationTokenStore,
            width: 570,
            height: 180,
            columns: [
                {stateId: 'grid-column-description', header: "{{i18n PLUGINS_CORE_AUTHENTICATION_COLUMN_TOKEN_DESCRIPTION}}", width: 250, dataIndex: 'description'},
                {stateId: 'grid-column-creation', header: "{{i18n PLUGINS_CORE_AUTHENTICATION_COLUMN_TOKEN_CREATION}}", width: 150, dataIndex: 'creationDate', renderer: Ametys.grid.GridColumnHelper.renderDate},
                // User tokens does not expires for the moment {stateId: 'grid-column-expiration', hidden: true, header: "{{i18n PLUGINS_CORE_AUTHENTICATION_COLUMN_TOKEN_EXPIRATION}}", width: 150, dataIndex: 'endDate', renderer: Ametys.grid.GridColumnHelper.renderDate},
                // User tokens are unlimited for the moment {stateId: 'grid-column-nb-left', hidden: true, header: "{{i18n PLUGINS_CORE_AUTHENTICATION_COLUMN_TOKEN_NB_USES_LEFT}}", width: 150, dataIndex: 'nbUsesLeft', renderer: this._renderCountLeft},
                {stateId: 'grid-column-delete', header: "-", width: 50, dataIndex: 'id', renderer: this._renderDeleteButton}
            ]
        });
	},
	
	/**
	 * @private
	 * Render the authentication token delete button
	 * @param {Number} id the token id
	 * @return {String} The html link for delete token
	 */
	_renderDeleteButton: function(id/*, metaData, record*/)
    {
    	return '<a class="delete-token" title="{{i18n PLUGINS_CORE_AUTHENTICATION_COLUMN_TOKEN_DELETE_TOOLTIP}}" href="javascript:(function(){Ametys.plugins.core.authentication.AuthenticationTokenActions._deleteAuthenticationToken(' + id + ')})()"><span class="a-grid-glyph ametysicon-rubbish7"></span></a>';
    },
	
    /**
     * @private
     * Count Left renderer
     * @param {Object} value The data value
     * @param {Object} metaData A collection of metadata about the current cell
     * @param {Ext.data.Model} record The record
     * @return {String} The html representation of the count (number or ∞ )
     */
    _renderCountLeft: function(value, metaData, record)
    {
        return value == null ? '&infin;' : value;
    },
    
    /**
	 * @private 
	 * Delete the authentication token
	 * @param {Number} tokenId the id of the token to delete
	 */
    _deleteAuthenticationToken: function(tokenId)
    {
        var record = this._authenticationTokenStore.getById(tokenId);
        if (!record)
        {
            return;
        }
        
        Ametys.Msg.confirm(
            "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_DELETE_TITLE}}",
            "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_DELETE_CONFIRM}}" + "\"" + record.get('description') + "\" ?",
            function (answer)
            {
                if (answer == 'yes')
                {
                    Ametys.plugins.core.authentication.AuthenticationTokenDAO.deleteAuthenticationToken([[tokenId]], this._deleteAuthenticationTokenCB, {scope: this, waitMessage: { target: this._authenticationTokenBox }});
                }
            },
            this
        );
    },
    
    /**
	 * @private 
	 * Callback function called after authentication token delete process
	 * @param {Object} response the callback response
     * @param {Object} args the callback argument
	 */
    _deleteAuthenticationTokenCB: function(response, args)
    {
    	this._authenticationTokenStore.load();
    },
    
	/**
	 * @private 
	 * Open the box to generate new authentication token
	 */
	_openGenerateTokenBox: function()
	{
		this._generateTokenFormPanel = Ext.create('Ext.form.Panel', {
	        border: false,
	        items: [
	        	{
                    xtype: 'component',
                    html: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_FORM_HINT}}",
                    cls: 'a-text'
                },
                {
                    xtype: 'textfield',
                    name: 'description',
                    itemId: 'description',
                    width: 500,
                    allowBlank: false,
                    labelAlign: 'right',
                    labelSeparator: '',
                    fieldLabel: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_FORM_DESCRIPTION_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_FORM_DESCRIPTION_DESC}}"
                }
	        ]
 		});
 		
		this._generateTokenBox = Ext.create('Ametys.window.DialogBox', {
			title: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_FORM_BOX_LABEL}}",
            iconCls: 'ametysicon-key162',
            
            width: 590, 
	        scrollable: false,
            
            items: [this._generateTokenFormPanel],
            
            defaultFocus: 'description',
            referenceHolder: true,
            defaultButton: 'validate',
            
            buttons: [{
            	reference: 'validate',
                text: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_BTN_VALIDATE}}",
                handler: this._generateToken,
                scope: this
            }, {
                text: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_BTN_CANCEL}}",
                handler : function () { this._generateTokenBox.close()},
				scope: this
            }]    
		});
		
		this._generateTokenBox.show();
	},
	
	/**
	 * @private 
	 * Generate authentication token
	 */
	_generateToken: function()
	{
		var form = this._generateTokenFormPanel.getForm();
        if (!form.isValid())
        {
        	return;
        }
        
        var values = form.getValues();
        Ametys.plugins.core.authentication.AuthenticationTokenDAO.generateAuthenticationToken([values], this._generateTokenCB, {scope: this, waitMessage: { target: this._generateTokenBox }});
	},
	
	/**
	 * @private 
	 * Callback function called after authentication token generation process
	 */
	_generateTokenCB: function (token, args)
    {
    	if (token)
    	{
    		this._generateTokenBox.close();
    		this._openValidateTokenBox(token);
    	}
    	else
		{
    		Ametys.Msg.show({
                title: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_ERROR_TITLE}}",
                msg: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_ERROR_MSG}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.ERROR
       	 	});	
		}
    },
    
    /**
	 * @private 
	 * Open the box with the token value
	 * @param {String} token the token value to display
	 */
    _openValidateTokenBox: function (token)
    {
    	this._validatedTokenPanel = this._createValidateTokenPanel(token);
		
    	this._validatedTokenBox = Ext.create('Ametys.window.DialogBox', {
			title: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_READY_BOX_LABEL}}",
            iconCls: 'ametysicon-key162',
            
            width: 800, 
	        scrollable: false,
            
            items: [{
	                xtype: 'component',
	                html: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_READY_HINT}}",
	                cls: 'a-text'
	            },
	            this._validatedTokenPanel
            ],
            
            defaultFocus: 'tokentext',
            selectDefaultFocus: true,
            
            referenceHolder: true,
            defaultButton: 'close',
            
            buttons: [{
            	reference: 'close',
                text: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_READY_TOKEN_VALUE_BTN_OK}}",
                handler : this._closeValidatedTokenBox,
				scope: this
            }]    
		});
		
		this._validatedTokenBox.show();
    },
    
    /**
	 * @private 
	 * Create the panel with the token displayed
	 * @param {String} token the token value to display
	 */
    _createValidateTokenPanel: function(token)
    {
    	this._validateTokenText = Ext.create('Ext.form.TextField', {
            value: token,
            width: 720,
            itemId: 'tokentext',
            name: 'tokentext',
            labelAlign: 'right',
            labelSeparator: '',
            editable: true,
            fieldLabel: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_READY_TOKEN_VALUE_LABEL}}"
    	});
    	
    	var panel = Ext.create('Ext.Container', {
    	    width: 800,
    	    layout: {
    	        type: 'hbox',
    	        align: 'stretch'
    	    },
    	    items: [
    	    	this._validateTokenText,
    	    	{
	    	        xtype: 'button',
	    	        iconCls: 'ametysicon-document28',
	    	        margin: '0 0 0 10',
	    	        tooltip: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_READY_TOKEN_COPY_BTN_TOOLTIP}}",
	                handler: function() {
	                	this._validateTokenText.selectText();
	                	if (!document.execCommand("copy"))
                		{
	                		Ametys.Msg.show({
	                            title: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_READY_TOKEN_COPY_BTN_ERROR_TITLE}}",
	                            msg: "{{i18n PLUGINS_CORE_AUTHENTICATION_TOKEN_GENERATE_TOKEN_READY_TOKEN_COPY_BTN_ERROR_MSG}}",
	                            buttons: Ext.Msg.OK,
	                            icon: Ext.MessageBox.ERROR
	                   	 	});
                		}
	                },
	                scope: this
    	    	}]
    	});
    	
    	return panel;
    },
    
    /**
	 * @private 
	 * Close the validated token box and refresh store
	 */
    _closeValidatedTokenBox: function ()
    {
    	this._validatedTokenBox.close();
    	this._authenticationTokenStore.load();
    }
});