/**
 * @description logAdapter which will be used for logging.
 * @param configure Configures Adapter for logging.
 * @param debug logs directory path absolute/relative.
 * @param info Name of log file to write logs.
 * @param error Name of log file to write logs.
 * @param getTransports Returns transports for logging.
 * @param getWriteableStream Returns the WriteableStream to file.
*/
export interface ILogAdapter {
  /**
   * @description configures the adapter
  */
  configure(): void;

  /**
  * @description creates and outputs debug log.
  * @param message  message to be logged.
  * @param args additional arguments to be used in logging.
  */
  debug(msg: any, ...args: any[]): void;

  /**
  * @description creates and outputs info log.
  * @param message  message to be logged.
  * @param args additional arguments to be used in logging.
  */
  info(msg: any, ...args: any[]): void;

  /**
  * @description creates and outputs error log.
  * @param message  message to be logged.
  * @param args additional arguments to be used in logging.
  */
  error(msg: any, ...args: any[]): void;

  /**
  * @description Use for logging system error.
  * @param message  message to be logged.
  * @param args additional arguments to be used in logging.
  */
  fatal(msg: any, ...args: any[]): void;
  getTansports(): Array<any>;
  getWriteableStream?(): WritableStream;
}

/**
 * @description logOptions to configure logger.
 * @param level Logging level use debug for production.
 * @param logPath logs directory path absolute/relative.
 * @param logFile Name of log file to write logs.
*/
export interface ILogOptions {
  level: string;
  logPath: string;
  logFile: string;
}

/**
 * @class
 * @description Logger class should be used to configure the adapters. It is the main entry point of SDK.
 * @param defaultScope modulename to be used in logging will be truncated to 6 chars.
 * @param AdapterMap map storage for multiple adapters.
 * @param LogOptions logging options to configure logger.
 * @param AdapterName name of adapter currently configured.
*/
export class Logger {

  static defaultScope: string;
  static AdapterMap: Map<string, ILogAdapter>;
  static LogOptions: ILogOptions;
  static AdapterName: string;

  private Adapter: ILogAdapter;
  /**
   * @constructor creates the new instance of Logger.
   * @param scope module/filename to be used for logging.
   * @param context microservice name that will be used throughout your logs.
   */
  constructor(scope: string, context?: any);

  /**
   * @static
   * @description Adds adapter to in memory map to support multiple adapters.
   * @param adapterName name of adapter to be used for logging eg: pino, winston, bunyan.
   * @param adapterInstance LogAdapter instance.
   * @returns void
   */
  static addAdapter(adapterName: string, adapterInstance: ILogAdapter): void;

  /**
   * @static
   * @description sets the adapter name for logging.
   * @param adapterName name of adapter eg: pino, winston, bunyan.
   * @returns ILogAdapter
   */
  static setAdapter(adapterName?: string): ILogAdapter;
  /**
   * @static
   * @description It will return the name of adapter currently set.
   * @returns Name of currently configured adapter
  */
  static getAdapter(): string;

  /**
   * @static
   * @description sets the logger options for logging.
   * @param logOptions log Options for logging.
   */
  static setLoggerOptions(logOptions: ILogOptions): void;

  /**
   * @description parses path to scope for logging
   * @returns string
  */
  static partPathToScope(scopePath: string): string;


  /**
   * @description creates and outputs debug log.
   * @param  message  message to be logged.
   * @param args additional arguments to be used in logging.
   * @note Last argument after data arg will be used for correlationIDs and should be JSONObject
   * @example logger.debug('debug message', eventData, correlationDataJSON)
  */
  public debug(msg: any, ...args: any[]): void;

  /**
   * @description creates and outputs info log.
   * @param message  message to be logged.
   * @param args additional arguments to be used in logging.
   * @note Last argument after data arg will be used for correlationIDs and should be JSONObject
   * @example logger.info('info message', eventData, correlationDataJSON)
  */
  public info(msg: any, ...args: any[]): void;

  /**
   * @description creates and outputs error log.
   * @param message  message to be logged.
   * @param args additional arguments to be used in logging.
   * @note Last argument after data arg will be used for correlationIDs and should be JSONObject
   * @example logger.error('apperror', new Error('customerror'))
  */
  public error(msg: any, error: Error, ...args: any[]): void;

  /**
   * @description  logs system error.
   * @param message  message to be logged.
   * @param args additional arguments to be used in logging.
   * @note Last argument after data arg will be used for correlationIDs and should be JSONObject
   * @example logger.fatal('dberror', new Error('customerror'))
  */
  public fatal(msg: any, error: Error, ...args: any[]): void;

  /**
   * @description creates and outputs log.
   * @param level level to be used for log.
   * @param message  message to be logged.
   * @param args additional arguments to be used in logging.
   * @note Last argument after data arg will be used for correlationIDs and should be JSONObject
   * @example logger.error('info', 'my info message', { user_id: 1 })
  */
  public log(level: string, msg: string, ...args: any[]): void;
}

/**
 * @description LoggerFactory creates the instance of the adapter based on configurations.</p>
 */
declare class LoggerFactory {
  /**
   * @description - gets the instances of the adapter for defined scope</p>
   * @param adapterName - <p>name of adapter to be used for logging</p>
   * @param logOptions - <p>LogOptions for logging</p>
   * @returns {ILogAdapter}
   */
  static getAdapter(adapterName: 'pino' | 'winston' | 'bunyan', logOptions: ILogOptions): ILogAdapter;
}

