/*
 * Copyright © 2012, 2013 Pedro Agullo Soliveres.
 * 
 * This file is part of Log4js-ext.
 *
 * Log4js-ext is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License.
 *
 * Commercial use is permitted to the extent that the code/component(s)
 * do NOT become part of another Open Source or Commercially developed
 * licensed development library or toolkit without explicit permission.
 *
 * Log4js-ext is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Log4js-ext.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * This software uses the ExtJs library (http://extjs.com), which is 
 * distributed under the GPL v3 license (see http://extjs.com/license).
 */

/*jslint strict:false */
(function() {
   //"use strict"; //$NON-NLS-1$

   /**
    * An appender that performs remote logging sending a POST request 
    * to the server.
    * 
    * There are three standard remote appender types, one for log4j
    * (see {@link Sm.log.remote.RemoteAppender#createLog4jAppender}), 
    * another one for slf4j (see 
    * {@link Sm.log.remote.RemoteAppender#createSlf4jAppender}), and a
    * third one for Apache Commons Logging (see 
    * {@link Sm.log.remote.RemoteAppender#createApacheCommonsLoggingAppender}).
    * 
    * It is possible to define new remote appenders once they are
    * implemented at the server side.
    */
   Ext.define('Sm.log.remote.RemoteAppender', { //$NON-NLS-1$
      extend : 'Sm.log.AppenderBase',

      uses: [
             'Sm.log.util.Debug',
             'Sm.log.util.Assert'],
      
      config : {
         /**
          * @cfg {String} [=defined in the constructor] (required) 
          * @accessor
          * @readonly
          * 
          * The logger name for the logger we want to use.
          * 
          * This name identifies the logger type in the server side, and
          * must be the same name used there.
          * 
          */
         loggerName : null,
         
         /**
          * @private
          * @method setLoggerName
          */

         /**
         * @cfg {String} [=defined in the constructor] (required) 
         * @accessor
         * @readonly
         * 
         * The url to which to send the log data.
         * 
         */
         url : null

         /**
          * @private
          * @method setUrl
          */
      },
      
      statics : {
         /**
          * Creates a remote log4j appender.
          * 
          * @static
          * @param url {String} The url to which to send the log data.
          * @returns {Sm.log.remote.RemoteAppender}
          */
         createLog4jAppender : function (url ) {
            Sm.log.util.Assert.assert(url);
            return new Sm.log.remote.RemoteAppender(
                  {loggerName: 'log4j', url : url});
         },

         /**
          * Creates a remote slf4j appender.
          * 
          * @static
          * @param url {String} The url to which to send the log data.
          * @returns {Sm.log.remote.RemoteAppender}
          */
         createSlf4jAppender : function (url ) {
            Sm.log.util.Assert.assert(url);
            return new Sm.log.remote.RemoteAppender(
                  {loggerName: 'slf4j', url : url});
         },

         /**
          * Creates a remote Apache Commons Logging appender.
          * 
          * @static
          * @param url {String} The url to which to send the log data.
          * @returns {Sm.log.remote.RemoteAppender}
          */
         createApacheCommonsLoggingAppender : function (url ) {
            Sm.log.util.Assert.assert(url);
            return new Sm.log.remote.RemoteAppender(
                  {loggerName: 'apacheCommons', url : url});
         }      
      },
      
      /**
       * @private Package
       * 
       * Creates a new appender.
       * 
       * You should preferably use 
       * {@link Sm.log.remote.RemoteAppender#createLog4jAppender},
       * {@link Sm.log.remote.RemoteAppender#createSlf4jAppender} or
       * {@link Sm.log.remote.RemoteAppender#createApacheCommonsLoggingAppender}
       * 
       * @param cfg
       */
      constructor : function(cfg) {
         this.callParent(arguments);
         Sm.log.util.Assert.assert(cfg);
         Sm.log.util.Assert.assert(cfg.loggerName);
         
         // We need a layout that does not highlight logged objects,
         // for remote loggers do not understand HTML as a rule
         this.setLayout(new Sm.log.LayoutBase());
         this.getLayout().highlightLoggedObject = false;
      },
      
      /**
       * @protected
       * 
       * @inheritDoc
       */
      doLog : function(logEvent) {
         var params;
         
         // Add data that is relevant to server
         logEvent.timeMillis = logEvent.time.getTime();
         
         // Remove data that is irrelevant to server
         delete logEvent.time;    // Wants timeMillis & formattedTime
         delete logEvent.message; // Wants formattedMessage
         delete logEvent.formatParams; // Server can't format with js object
         delete logEvent.loggedObject; // Server can't cope with js object
         delete logEvent.levelLevel;   // Makes no sense for server
         
         logEvent.logger = this.getLoggerName();
         
         params = logEvent;
         Ext.Ajax.request({
            url: this.getUrl(), 
            method: 'POST',
            params: params,
            success: function (result, request){
               Sm.log.util.Assert.assert( result.responseText === "true" );
            },
            failure: function (result, request){
               Sm.log.util.Debug.abort();
            }
         });
      }
   });
}());