import { AbstractLogger } from 'tachyon-logger/abstractLogger';
import { LogLevel, LogMessage } from 'tachyon-logger/logger';
import {
  eventLoggerMiddleware,
  flattenMessageLoggerMiddleware,
  singleStringLoggerMiddleware,
} from 'tachyon-logger/loggerMiddleware';
import { JSONifySerializer } from 'tachyon-logger/serializers';

/**
 * Candidate methods for debug messages.
 */
type DebugLogMethodCandidate = 'debug' | 'log';

/**
 * A logger that outputs all logs to the console.
 */
export class ConsoleLogger extends AbstractLogger {
  /**
   * Not all browsers support console.debug, this const indicates the safe
   * debug method name.
   */
  private readonly debugLogMethod: DebugLogMethodCandidate = console.debug
    ? 'debug'
    : 'log';

  /* tslint:disable:no-console */
  public debug(message: LogMessage): void {
    console[this.debugLogMethod](this.getLogOutput(LogLevel.DEBUG, message));
  }

  public log(message: LogMessage): void {
    console.log(this.getLogOutput(LogLevel.DEBUG, message));
  }

  public info(message: LogMessage): void {
    console.info(this.getLogOutput(LogLevel.INFO, message));
  }

  public warn(message: LogMessage): void {
    console.warn(this.getLogOutput(LogLevel.WARNING, message));
  }

  public error(message: LogMessage): void {
    console.error(this.getLogOutput(LogLevel.ERROR, message));
  }
  /* tslint:enable:no-console */
}

/**
 * A global logger that only logs to the console.
 */
export const consoleLogger = new ConsoleLogger(
  [
    singleStringLoggerMiddleware,
    flattenMessageLoggerMiddleware,
    eventLoggerMiddleware,
  ],
  JSONifySerializer,
);
