| var util = require('util') | 
| var _ = require('lodash') | 
|   | 
| var loggerInstance | 
|   | 
| var defaultProvider = { | 
|   log: console.log, | 
|   debug: console.log, // use .log(); since console does not have .debug() | 
|   info: console.info, | 
|   warn: console.warn, | 
|   error: console.error | 
| } | 
|   | 
| // log level 'weight' | 
| var LEVELS = { | 
|   debug: 10, | 
|   info: 20, | 
|   warn: 30, | 
|   error: 50, | 
|   silent: 80 | 
| } | 
|   | 
| module.exports = { | 
|   // singleton | 
|   getInstance: function() { | 
|     if (!loggerInstance) { | 
|       loggerInstance = new Logger() | 
|     } | 
|   | 
|     return loggerInstance | 
|   }, | 
|   getArrow: getArrow | 
| } | 
|   | 
| function Logger() { | 
|   var logLevel | 
|   var provider | 
|   | 
|   var api = { | 
|     log: log, | 
|     debug: debug, | 
|     info: info, | 
|     warn: warn, | 
|     error: error, | 
|     setLevel: function(v) { | 
|       if (isValidLevel(v)) { | 
|         logLevel = v | 
|       } | 
|     }, | 
|     setProvider: function(fn) { | 
|       if (fn && isValidProvider(fn)) { | 
|         provider = fn(defaultProvider) | 
|       } | 
|     } | 
|   } | 
|   | 
|   init() | 
|   | 
|   return api | 
|   | 
|   function init() { | 
|     api.setLevel('info') | 
|     api.setProvider(function() { | 
|       return defaultProvider | 
|     }) | 
|   } | 
|   | 
|   // log will log messages, regardless of logLevels | 
|   function log() { | 
|     provider.log(_interpolate.apply(null, arguments)) | 
|   } | 
|   | 
|   function debug() { | 
|     if (_showLevel('debug')) { | 
|       provider.debug(_interpolate.apply(null, arguments)) | 
|     } | 
|   } | 
|   | 
|   function info() { | 
|     if (_showLevel('info')) { | 
|       provider.info(_interpolate.apply(null, arguments)) | 
|     } | 
|   } | 
|   | 
|   function warn() { | 
|     if (_showLevel('warn')) { | 
|       provider.warn(_interpolate.apply(null, arguments)) | 
|     } | 
|   } | 
|   | 
|   function error() { | 
|     if (_showLevel('error')) { | 
|       provider.error(_interpolate.apply(null, arguments)) | 
|     } | 
|   } | 
|   | 
|   /** | 
|    * Decide to log or not to log, based on the log levels 'weight' | 
|    * @param  {String}  showLevel [debug, info, warn, error, silent] | 
|    * @return {Boolean} | 
|    */ | 
|   function _showLevel(showLevel) { | 
|     var result = false | 
|     var currentLogLevel = LEVELS[logLevel] | 
|   | 
|     if (currentLogLevel && currentLogLevel <= LEVELS[showLevel]) { | 
|       result = true | 
|     } | 
|   | 
|     return result | 
|   } | 
|   | 
|   // make sure logged messages and its data are return interpolated | 
|   // make it possible for additional log data, such date/time or custom prefix. | 
|   function _interpolate() { | 
|     var fn = _.spread(util.format) | 
|     var result = fn(_.slice(arguments)) | 
|   | 
|     return result | 
|   } | 
|   | 
|   function isValidProvider(fnProvider) { | 
|     var result = true | 
|   | 
|     if (fnProvider && !_.isFunction(fnProvider)) { | 
|       throw new Error('[HPM] Log provider config error. Expecting a function.') | 
|     } | 
|   | 
|     return result | 
|   } | 
|   | 
|   function isValidLevel(levelName) { | 
|     var validLevels = _.keys(LEVELS) | 
|     var isValid = _.includes(validLevels, levelName) | 
|   | 
|     if (!isValid) { | 
|       throw new Error('[HPM] Log level error. Invalid logLevel.') | 
|     } | 
|   | 
|     return isValid | 
|   } | 
| } | 
|   | 
| /** | 
|  * -> normal proxy | 
|  * => router | 
|  * ~> pathRewrite | 
|  * ≈> router + pathRewrite | 
|  * | 
|  * @param  {String} originalPath | 
|  * @param  {String} newPath | 
|  * @param  {String} originalTarget | 
|  * @param  {String} newTarget | 
|  * @return {String} | 
|  */ | 
| function getArrow(originalPath, newPath, originalTarget, newTarget) { | 
|   var arrow = ['>'] | 
|   var isNewTarget = originalTarget !== newTarget // router | 
|   var isNewPath = originalPath !== newPath // pathRewrite | 
|   | 
|   if (isNewPath && !isNewTarget) { | 
|     arrow.unshift('~') | 
|   } else if (!isNewPath && isNewTarget) { | 
|     arrow.unshift('=') | 
|   } else if (isNewPath && isNewTarget) { | 
|     arrow.unshift('≈') | 
|   } else { | 
|     arrow.unshift('-') | 
|   } | 
|   | 
|   return arrow.join('') | 
| } |