"use strict" ;

import LoggerLevel from '../LoggerLevel'
import LineFormattedTarget from './LineFormattedTarget'

const colors = require('colors') ;

/**
 * Provides a logger target that uses the global trace() method to output log messages.
 * @name NodeTarget
 * @memberof system.logging.targets
 * @class
 * @extends system.logging.targets.LineFormattedTarget
 * @param {Object} init - A generic object containing properties with which to populate the newly instance. If this argument is <code>null</code>, it is ignored.
 * @example
 * var Log           = system.logging.Log ;
 * var LoggerLevel   = system.logging.LoggerLevel ;
 * var NodeTarget = system.logging.targets.TraceTarget ;
 *
 * var target = new NodeTarget
 * ({
 *     includeChannel      : true  ,
 *     includeDate         : false  ,
 *     includeLevel        : true  ,
 *     includeLines        : true  ,
 *     includeMilliseconds : true  ,
 *     includeTime         : true
 * }) ;
 *
 * target.filters = ["*"] ;
 * target.level   = LoggerLevel.ALL ;
 *
 * // target.useColors = false ;
 *
 * var logger = Log.getLogger('test') ;
 *
 * logger.log( "Here is some myDebug info : {0} and {1}", 2.25 , true ) ;
 * logger.debug( "Here is some debug message." ) ;
 * logger.info( "Here is some info message." ) ;
 * logger.warning( "Here is some warn message." ) ;
 * logger.error( "Here is some error message." ) ;
 * logger.critical( "Here is some critical error..." ) ;
 *
 * target.includeDate    = false ;
 * target.includeTime    = false ;
 * target.includeChannel = false ;
 *
 * logger.info( "test : [{0}, {1}, {2}]", 2, 4, 6 ) ;
 */
export default function NodeTarget( init = null )
{
    /**
     * Indicates if the channel for this target use the node colors module (https://github.com/Marak/colors.js).
     * @name useColors
     * @memberof system.logging.targets.NodeTarget
     * @instance
     * @type boolean
     * @default true
     */
    this.useColors = true ;

    colors.setTheme
    ({
        critical : 'cyan',
        debug    : 'blue',
        error    : 'red' ,
        info     : 'green',
        log      : 'grey',
        warning  : 'yellow',
        wtf      : 'rainbow'
    });

    LineFormattedTarget.call( this , init ) ;
}

NodeTarget.prototype = Object.create( LineFormattedTarget.prototype ,
{
    constructor : { value : NodeTarget } ,

    /**
     * Descendants of this class should override this method to direct the specified message to the desired output.
     * @param {string} message - String containing preprocessed log message which may include time, date, channel, etc.
     * based on property settings, such as <code>includeDate</code>, <code>includeChannel</code>, etc.
     * @param {system.logging.LoggerLevel} level - The level of the log message.
     * @name internalLog
     * @memberof system.logging.targets.NodeTarget
     * @function
     * @instance
     */
    internalLog : { value : function( message , level ) //jshint ignore:line
    {
        if( console )
        {
            switch( level )
            {
                case LoggerLevel.CRITICAL :
                {
                    console.trace( this.useColors ? message.critical : message ) ;
                    break ;
                }
                case LoggerLevel.DEBUG :
                {
                    console.log( this.useColors ? message.debug : message ) ;
                    break ;
                }
                case LoggerLevel.ERROR :
                {
                    console.error( this.useColors ? message.error : message ) ;
                    break ;
                }
                case LoggerLevel.INFO :
                {
                    console.info( this.useColors ? message.info : message ) ;
                    break ;
                }
                case LoggerLevel.WARNING :
                {
                    console.warn( this.useColors ? message.warning : message ) ;
                    break ;
                }
                case LoggerLevel.WTF :
                {
                    console.log( this.useColors ? message.wtf : message ) ;
                    break ;
                }
                default :
                case LoggerLevel.ALL :
                {
                    console.log( this.useColors ? message.log : message ) ;
                    break ;
                }
            }
        }
        else
        {
            throw new new ReferenceError('The console reference is unsupported.') ;
        }
    }}
});
