import { colors } from './colors.js';
/** Default logger implementation with colored output, query formatting, and namespace-based filtering. */
export class DefaultLogger {
  options;
  debugMode;
  writer;
  usesReplicas;
  highlighter;
  constructor(options) {
    this.options = options;
    this.debugMode = this.options.debugMode ?? false;
    this.writer = this.options.writer;
    this.usesReplicas = this.options.usesReplicas;
    this.highlighter = this.options.highlighter;
  }
  /**
   * @inheritDoc
   */
  log(namespace, message, context) {
    if (!this.isEnabled(namespace, context)) {
      return;
    }
    // clean up the whitespace
    message = message.replace(/\n/g, '').replace(/ +/g, ' ').trim();
    // use red for error levels
    if (context?.level === 'error') {
      message = colors.red(message);
    }
    // use yellow for warning levels
    if (context?.level === 'warning') {
      message = colors.yellow(message);
    }
    const label = context?.label ? colors.cyan(`(${context.label}) `) : '';
    this.writer(colors.grey(`[${namespace}] `) + label + message);
  }
  /**
   * @inheritDoc
   */
  error(namespace, message, context) {
    this.log(namespace, message, { ...context, level: 'error' });
  }
  /**
   * @inheritDoc
   */
  warn(namespace, message, context) {
    this.log(namespace, message, { ...context, level: 'warning' });
  }
  /**
   * @inheritDoc
   */
  setDebugMode(debugMode) {
    this.debugMode = debugMode;
  }
  /** Checks whether logging is enabled for the given namespace, considering context overrides. */
  isEnabled(namespace, context) {
    if (context?.enabled !== undefined) {
      return context.enabled;
    }
    const debugMode = context?.debugMode ?? this.debugMode;
    if (namespace === 'deprecated') {
      const { ignoreDeprecations = false } = this.options;
      return Array.isArray(ignoreDeprecations)
        ? /* v8 ignore next */
          !ignoreDeprecations.includes(context?.label ?? '')
        : !ignoreDeprecations;
    }
    return !!debugMode && (!Array.isArray(debugMode) || debugMode.includes(namespace));
  }
  /**
   * @inheritDoc
   */
  logQuery(context) {
    const namespace = context.namespace ?? 'query';
    if (!this.isEnabled(namespace, context)) {
      return;
    }
    /* v8 ignore next */
    let msg = this.highlighter?.highlight(context.query) ?? context.query;
    if (context.took != null) {
      const meta = [`took ${context.took} ms`];
      if (context.results != null) {
        meta.push(`${context.results} result${context.results === 0 || context.results > 1 ? 's' : ''}`);
      }
      if (context.affected != null) {
        meta.push(`${context.affected} row${context.affected === 0 || context.affected > 1 ? 's' : ''} affected`);
      }
      msg += colors.grey(` [${meta.join(', ')}]`);
    }
    if (this.usesReplicas && context.connection) {
      msg += colors.cyan(` (via ${context.connection.type} connection '${context.connection.name}')`);
    }
    return this.log(namespace, msg, context);
  }
  /** Factory method for creating a new DefaultLogger instance. */
  static create(options) {
    return new DefaultLogger(options);
  }
}
