/**
 * This file is part of the vscode-helpers distribution.
 * Copyright (c) Marcel Joachim Kloubert.
 *
 * vscode-helpers 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, version 3.
 *
 * vscode-helpers 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 this program. If not, see <http://www.gnu.org/licenses/>.
 */ import * as Events from 'events' ; import * as Moment from 'moment' ; import * as vscode from 'vscode' ; import * as vscode_helpers from '../index' ; param { LogContext } context export type LogAction = ( context : LogContext ) => any ; /**
 * A log context.
 */ export interface LogContext { /**
     * The message.
     */ readonly message : any ; /**
     * The tag.
     */ readonly tag ? : string ; /**
     * The time.
     */ readonly time : Moment . Moment ; /**
     * The type.
     */ readonly type ? : LogType ; } /**
 * A log filter.
 */ export type LogFilter = ( context : LogContext ) => any ; /**
 * A logger.
 */ export interface Logger extends NodeJS . EventEmitter { /**
     * Logs an alert message.
     */ readonly alert : TypedLogAction ; /**
     * Logs a critical message.
     */ readonly crit : TypedLogAction ; /**
     * Logs a debug message.
     */ readonly debug : TypedLogAction ; /**
     * Logs an emergency message.
     */ readonly emerg : TypedLogAction ; /**
     * Logs an error message.
     */ readonly err : TypedLogAction ; /**
     * Logs an info message.
     */ readonly info : TypedLogAction ; param { LogType } The param { any } msg param { string } tag readonly log : ( type : LogType , msg : any , tag ? : string ) => PromiseLike < void > | void ; /**
     * Logs a note message.
     */ readonly notice : TypedLogAction ; /**
     * Logs a trace message.
     */ readonly trace : TypedLogAction ; /**
     * Logs a warning message.
     */ readonly warn : TypedLogAction ; } param { any } msg param { string } tag return { Logger } chainable export type TypedLogAction = ( msg : any , tag ? : string ) => Logger ; /**
 * List of log types.
 */ export enum LogType { /**
     * Emergency
     */ Emerg = 0 , /**
     * Alert
     */ Alert = 1 , /**
     * Critical
     */ Crit = 2 , /**
     * Error
     */ Err = 3 , /**
     * Warning
     */ Warn = 4 , /**
     * Notice
     */ Notice = 5 , /**
     * Informational
     */ Info = 6 , /**
     * Debug
     */ Debug = 7 , /**
     * Trace
     */ Trace = 8 } /**
 * A basic logger.
 */ export abstract class LoggerBase extends Events . EventEmitter implements Logger { inheritdoc public alert ( msg , tag ? ) { return this . logSync ( LogType . Alert , msg , tag ) ; } inheritdoc public crit ( msg , tag ? ) { return this . logSync ( LogType . Crit , msg , tag ) ; } inheritdoc public debug ( msg , tag ? ) { return this . logSync ( LogType . Debug , msg , tag ) ; } inheritdoc public emerg ( msg , tag ? ) { return this . logSync ( LogType . Emerg , msg , tag ) ; } inheritdoc public err ( msg , tag ? ) { return this . logSync ( LogType . Err , msg , tag ) ; } inheritdoc public info ( msg , tag ? ) { return this . logSync ( LogType . Info , msg , tag ) ; } inheritdoc public async log ( type , msg , tag ? ) { const CONTEXT = { message : msg , tag : this . normalizeTag ( tag ) , time : Moment ( ) , type : type , } ; const RAISE_EVENT = await Promise . resolve ( vscode_helpers . toBooleanSafe ( await this . onLog ( CONTEXT ) , true ) ) ; if ( RAISE_EVENT ) { this . emit ( 'log' , CONTEXT ) ; } } param { LogType } type param { any } msg param { string } tag protected logSync ( type , msg , tag ? ) { this . log ( type , msg , tag ) ; return this ; } param { string } tag return { string } protected normalizeTag ( tag ) { tag = vscode_helpers . normalizeString ( tag , s => s . toUpperCase ( ) . trim ( ) ) ; if ( '' === tag ) { tag = undefined ; } return tag ; } inheritdoc public notice ( msg , tag ? ) { return this . logSync ( LogType . Notice , msg , tag ) ; } param { LogContext } context return { Promise < any > } protected abstract onLog ( context ) ; inheritdoc public trace ( msg , tag ? ) { return this . logSync ( LogType . Trace , msg , tag ) ; } inheritdoc public warn ( msg , tag ? ) { return this . logSync ( LogType . Warn , msg , tag ) ; } } /**
 * A logger based on actions.
 */ export class ActionLogger extends LoggerBase { private _actions : LogAction [ ] = [ ] ; private _filters : LogFilter [ ] = [ ] ; param { LogAction } action return chainable public addAction ( action ) { this . _actions . push ( action ) ; return this ; } param { LogFilter } filter return chainable public addFilter ( filter ) { this . _filters . push ( filter ) ; return this ; } return chainable public clear ( ) { return this . clearActions ( ) . clearFilters ( ) ; } return chainable public clearActions ( ) { this . _actions = [ ] ; return this ; } return chainable public clearFilters ( ) { this . _filters = [ ] ; return this ; } inheritdoc protected async onLog ( context ) { const ACTIONS = this . _actions || [ ] ; const FILTERS = this . _filters || [ ] ; for ( let i = 0 ; i < ACTIONS . length ; i ++ ) { try { const LOG_ACTION = ACTIONS [ i ] ; let doLog = true ; for ( let j = 0 ; j < FILTERS . length ; j ++ ) { try { const LOG_FILTER = FILTERS [ j ] ; doLog = vscode_helpers . toBooleanSafe ( await Promise . resolve ( LOG_FILTER ( context ) ) , true ) ; } catch { } if ( ! doLog ) { break ; } } if ( doLog ) { LOG_ACTION ( context ) ; } } catch { } } } } param { LogAction [ ] } actions return { vscode_helpers_logging . ActionLogger } export function createLogger ( ... actions ) { const NEW_LOGGER = new ActionLogger ( ) ; actions . forEach ( a => { NEW_LOGGER . addAction ( a ) ; } ) ; return NEW_LOGGER ; }