/*
 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.
 */

var ansi = require('ansi');
var EventEmitter = require('events').EventEmitter;
var CordovaError = require('./CordovaError/CordovaError');
var EOL = require('os').EOL;

var INSTANCE;

/**
 * @class CordovaLogger
 *
 * Implements logging facility that anybody could use. Should not be
 *   instantiated directly, `CordovaLogger.get()` method should be used instead
 *   to acquire logger instance
 */
function CordovaLogger () {
    this.levels = {};
    this.colors = {};
    this.stdout = process.stdout;
    this.stderr = process.stderr;

    this.stdoutCursor = ansi(this.stdout);
    this.stderrCursor = ansi(this.stderr);

    this.addLevel('verbose', 1000, 'grey');
    this.addLevel('normal', 2000);
    this.addLevel('warn', 2000, 'yellow');
    this.addLevel('info', 3000, 'blue');
    this.addLevel('error', 5000, 'red');
    this.addLevel('results', 10000);

    this.setLevel('normal');
}

/**
 * Static method to create new or acquire existing instance.
 *
 * @return  {CordovaLogger}  Logger instance
 */
CordovaLogger.get = function () {
    return INSTANCE || (INSTANCE = new CordovaLogger());
};

CordovaLogger.VERBOSE = 'verbose';
CordovaLogger.NORMAL = 'normal';
CordovaLogger.WARN = 'warn';
CordovaLogger.INFO = 'info';
CordovaLogger.ERROR = 'error';
CordovaLogger.RESULTS = 'results';

/**
 * Emits log message to process' stdout/stderr depending on message's severity
 *   and current log level. If severity is less than current logger's level,
 *   then the message is ignored.
 *
 * @param   {String}  logLevel  The message's log level. The logger should have
 *   corresponding level added (via logger.addLevel), otherwise
 *   `CordovaLogger.NORMAL` level will be used.
 * @param   {String}  message   The message, that should be logged to process'
 *   stdio
 *
 * @return  {CordovaLogger}     Current instance, to allow calls chaining.
 */
CordovaLogger.prototype.log = function (logLevel, message) {
    // if there is no such logLevel defined, or provided level has
    // less severity than active level, then just ignore this call and return
    if (!this.levels[logLevel] || this.levels[logLevel] < this.levels[this.logLevel]) {
        // return instance to allow to chain calls
        return this;
    }

    var isVerbose = this.logLevel === 'verbose';
    var cursor = this.stdoutCursor;

    if (message instanceof Error || logLevel === CordovaLogger.ERROR) {
        message = formatError(message, isVerbose);
        cursor = this.stderrCursor;
    }

    var color = this.colors[logLevel];
    if (color) {
        cursor.bold().fg[color]();
    }

    cursor.write(message).reset().write(EOL);

    return this;
};

/**
 * Adds a new level to logger instance. This method also creates a shortcut
 *   method to log events with the level provided (i.e. after adding new level
 *   'debug', the method `debug(message)`, equal to logger.log('debug', message),
 *   will be added to logger instance)
 *
 * @param  {String}  level     A log level name. The levels with the following
 *   names added by default to every instance: 'verbose', 'normal', 'warn',
 *   'info', 'error', 'results'
 * @param  {Number}  severity  A number that represents level's severity.
 * @param  {String}  color     A valid color name, that will be used to log
 *   messages with this level. Any CSS color code or RGB value is allowed
 *   (according to ansi documentation:
 *   https://github.com/TooTallNate/ansi.js#features)
 *
 * @return  {CordovaLogger}     Current instance, to allow calls chaining.
 */
CordovaLogger.prototype.addLevel = function (level, severity, color) {

    this.levels[level] = severity;

    if (color) {
        this.colors[level] = color;
    }

    // Define own method with corresponding name
    if (!this[level]) {
        this[level] = this.log.bind(this, level);
    }

    return this;
};

/**
 * Sets the current logger level to provided value. If logger doesn't have level
 *   with this name, `CordovaLogger.NORMAL` will be used.
 *
 * @param  {String}  logLevel  Level name. The level with this name should be
 *   added to logger before.
 *
 * @return  {CordovaLogger}     Current instance, to allow calls chaining.
 */
CordovaLogger.prototype.setLevel = function (logLevel) {
    this.logLevel = this.levels[logLevel] ? logLevel : CordovaLogger.NORMAL;

    return this;
};

/**
 * Adjusts the current logger level according to the passed options.
 *
 * @param   {Object|Array}  opts  An object or args array with options
 *
 * @return  {CordovaLogger}     Current instance, to allow calls chaining.
 */
CordovaLogger.prototype.adjustLevel = function (opts) {
    if (opts.verbose || (Array.isArray(opts) && opts.indexOf('--verbose') !== -1)) {
        this.setLevel('verbose');
    } else if (opts.silent || (Array.isArray(opts) && opts.indexOf('--silent') !== -1)) {
        this.setLevel('error');
    }

    return this;
};

/**
 * Attaches logger to EventEmitter instance provided.
 *
 * @param   {EventEmitter}  eventEmitter  An EventEmitter instance to attach
 *   logger to.
 *
 * @return  {CordovaLogger}     Current instance, to allow calls chaining.
 */
CordovaLogger.prototype.subscribe = function (eventEmitter) {

    if (!(eventEmitter instanceof EventEmitter)) { throw new Error('Subscribe method only accepts an EventEmitter instance as argument'); }

    eventEmitter.on('verbose', this.verbose)
        .on('log', this.normal)
        .on('info', this.info)
        .on('warn', this.warn)
        .on('warning', this.warn)
        // Set up event handlers for logging and results emitted as events.
        .on('results', this.results);

    return this;
};

function formatError (error, isVerbose) {
    var message = '';

    if (error instanceof CordovaError) {
        message = error.toString(isVerbose);
    } else if (error instanceof Error) {
        if (isVerbose) {
            message = error.stack;
        } else {
            message = error.message;
        }
    } else {
        // Plain text error message
        message = error;
    }

    if (typeof message === 'string' && message.toUpperCase().indexOf('ERROR:') !== 0) {
        // Needed for backward compatibility with external tools
        message = 'Error: ' + message;
    }

    return message;
}

module.exports = CordovaLogger;
