// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Provides APIs for debugging and error logging. This library introduces
 * abstractions similar to those used in other languages, such as the Closure JS
 * Logger and java.util.logging.Logger.
 */
library logging;

/**
 * Whether to allow fine-grain logging and configuration of loggers in a
 * hierarchy. When false, all logging is merged in the root logger.
 */
bool hierarchicalLoggingEnabled = false;

/**
 * Level for the root-logger. This will be the level of all loggers if
 * [hierarchicalLoggingEnabled] is false.
 */
Level _rootLevel = Level.INFO;


/**
 * Use a [Logger] to log debug messages. [Logger]s are named using a
 * hierarchical dot-separated name convention.
 */
class Logger {
  /** Simple name of this logger. */
  final String name;

  /** The full name of this logger, which includes the parent's full name. */
  String get fullName =>
      (parent == null || parent.name == '') ? name : '${parent.fullName}.$name';

  /** Parent of this logger in the hierarchy of loggers. */
  final Logger parent;

  /** Logging [Level] used for entries generated on this logger. */
  Level _level;

  /** Children in the hierarchy of loggers, indexed by their simple names. */
  Map<String, Logger> children;

  /** Handlers used to process log entries in this logger. */
  List<LoggerHandler> _handlers;

  /**
   * Singleton constructor. Calling `new Logger(name)` will return the same
   * actual instance whenever it is called with the same string name.
   */
  factory Logger(String name) {
    if (name.startsWith('.')) {
      throw new ArgumentError("name shouldn't start with a '.'");
    }
    if (_loggers == null) _loggers = <String, Logger>{};
    if (_loggers.containsKey(name)) return _loggers[name];

    // Split hierarchical names (separated with '.').
    int dot = name.lastIndexOf('.');
    Logger parent = null;
    String thisName;
    if (dot == -1) {
      if (name != '') parent = new Logger('');
      thisName = name;
    } else {
      parent = new Logger(name.substring(0, dot));
      thisName = name.substring(dot + 1);
    }
    final res = new Logger._internal(thisName, parent);
    _loggers[name] = res;
    return res;
  }

  Logger._internal(this.name, this.parent)
      : children = new Map<String, Logger>() {
    if (parent != null) parent.children[name] = this;
  }

  /**
   * Effective level considering the levels established in this logger's parents
   * (when [hierarchicalLoggingEnabled] is true).
   */
  Level get level {
    if (hierarchicalLoggingEnabled) {
      if (_level != null) return _level;
      if (parent != null) return parent.level;
    }
    return _rootLevel;
  }

  /** Override the level for this particular [Logger] and its children. */
  set level(value) {
    if (hierarchicalLoggingEnabled && parent != null) {
      _level = value;
    } else {
      if (parent != null) {
        throw new UnsupportedError(
            'Please set "hierarchicalLoggingEnabled" to true if you want to '
            'change the level on a non-root logger.');
      }
      _rootLevel = value;
    }
  }

  /**
   * Returns an event manager for this [Logger]. You can listen for log messages
   * by adding a [LoggerHandler] to an event from the event manager, for
   * instance:
   *    logger.on.record.add((record) { ... });
   */
  LoggerEvents get on => new LoggerEvents(this);

  /** Adds a handler to listen whenever a log record is added to this logger. */
  void _addHandler(LoggerHandler handler) {
    if (hierarchicalLoggingEnabled || parent == null) {
      if (_handlers == null) {
        _handlers = new List<LoggerHandler>();
      }
      _handlers.add(handler);
    } else {
      root._addHandler(handler);
    }
  }

  /** Remove a previously added handler. */
  void _removeHandler(LoggerHandler handler) {
    if (hierarchicalLoggingEnabled || parent == null) {
      if (_handlers == null) return;
      int index = _handlers.indexOf(handler);
      if (index != -1) _handlers.removeRange(index, 1);
    } else {
      root._removeHandler(handler);
    }
  }

  /** Removes all handlers previously added to this logger. */
  void _clearHandlers() {
    if (hierarchicalLoggingEnabled || parent == null) {
      _handlers = null;
    } else {
      root._clearHandlers();
    }
  }

  /** Whether a message for [value]'s level is loggable in this logger. */
  bool isLoggable(Level value) => (value >= level);

  /**
   * Adds a log record for a [message] at a particular [logLevel] if
   * `isLoggable(logLevel)` is true. Use this method to create log entries for
   * user-defined levels. To record a message at a predefined level (e.g.
   * [Level.INFO], [Level.WARNING], etc) you can use their specialized methods
   * instead (e.g. [info], [warning], etc).
   */
  // TODO(sigmund): add support for logging exceptions.
  void log(Level logLevel, String message) {
    if (isLoggable(logLevel)) {
      var record = new LogRecord(logLevel, message, fullName);
      if (hierarchicalLoggingEnabled) {
        var target = this;
        while (target != null) {
          target._publish(record);
          target = target.parent;
        }
      } else {
        root._publish(record);
      }
    }
  }

  /** Log message at level [Level.FINEST]. */
  void finest(String message) => log(Level.FINEST, message);

  /** Log message at level [Level.FINER]. */
  void finer(String message) => log(Level.FINER, message);

  /** Log message at level [Level.FINE]. */
  void fine(String message) => log(Level.FINE, message);

  /** Log message at level [Level.CONFIG]. */
  void config(String message) => log(Level.CONFIG, message);

  /** Log message at level [Level.INFO]. */
  void info(String message) => log(Level.INFO, message);

  /** Log message at level [Level.WARNING]. */
  void warning(String message) => log(Level.WARNING, message);

  /** Log message at level [Level.SEVERE]. */
  void severe(String message) => log(Level.SEVERE, message);

  /** Log message at level [Level.SHOUT]. */
  void shout(String message) => log(Level.SHOUT, message);

  void _publish(LogRecord record) {
    if (_handlers != null) {
      _handlers.forEach((h) => h(record));
    }
  }

  /** Top-level root [Logger]. */
  static get root => new Logger('');

  /** All [Logger]s in the system. */
  static Map<String, Logger> _loggers;
}


/** Handler callback to process log entries as they are added to a [Logger]. */
typedef void LoggerHandler(LogRecord);


/** Event manager for a [Logger] (holds events that a [Logger] can fire). */
class LoggerEvents {
  final Logger _logger;

  LoggerEvents(this._logger);

  /** Event fired when a log record is added to a [Logger]. */
  LoggerHandlerList get record => new LoggerHandlerList(_logger);
}


/** List of handlers that will be called on a logger event. */
class LoggerHandlerList {
  Logger _logger;

  LoggerHandlerList(this._logger);

  void add(LoggerHandler handler) => _logger._addHandler(handler);
  void remove(LoggerHandler handler) => _logger._removeHandler(handler);
  void clear() => _logger._clearHandlers();
}


/**
 * [Level]s to control logging output. Logging can be enabled to include all
 * levels above certain [Level]. [Level]s are ordered using an integer
 * value [Level.value]. The predefined [Level] constants below are sorted as
 * follows (in descending order): [Level.SHOUT], [Level.SEVERE],
 * [Level.WARNING], [Level.INFO], [Level.CONFIG], [Level.FINE], [Level.FINER],
 * [Level.FINEST], and [Level.ALL].
 *
 * We recommend using one of the predefined logging levels. If you define your
 * own level, make sure you use a value between those used in [Level.ALL] and
 * [Level.OFF].
 */
class Level implements Comparable<Level> {

  // TODO(sigmund): mark name/value as 'const' when the language supports it.
  final String name;

  /**
   * Unique value for this level. Used to order levels, so filtering can exclude
   * messages whose level is under certain value.
   */
  final int value;

  const Level(this.name, this.value);

  /** Special key to turn on logging for all levels ([value] = 0). */
  static const Level ALL = const Level('ALL', 0);

  /** Special key to turn off all logging ([value] = 2000). */
  static const Level OFF = const Level('OFF', 2000);

  /** Key for highly detailed tracing ([value] = 300). */
  static const Level FINEST = const Level('FINEST', 300);

  /** Key for fairly detailed tracing ([value] = 400). */
  static const Level FINER = const Level('FINER', 400);

  /** Key for tracing information ([value] = 500). */
  static const Level FINE = const Level('FINE', 500);

  /** Key for static configuration messages ([value] = 700). */
  static const Level CONFIG = const Level('CONFIG', 700);

  /** Key for informational messages ([value] = 800). */
  static const Level INFO = const Level('INFO', 800);

  /** Key for potential problems ([value] = 900). */
  static const Level WARNING = const Level('WARNING', 900);

  /** Key for serious failures ([value] = 1000). */
  static const Level SEVERE = const Level('SEVERE', 1000);

  /** Key for extra debugging loudness ([value] = 1200). */
  static const Level SHOUT = const Level('SHOUT', 1200);

  bool operator ==(Level other) => other != null && value == other.value;
  bool operator <(Level other) => value < other.value;
  bool operator <=(Level other) => value <= other.value;
  bool operator >(Level other) => value > other.value;
  bool operator >=(Level other) => value >= other.value;
  int compareTo(Level other) => value - other.value;
  int get hashCode => value;
  String toString() => name;
}


/**
 * A log entry representation used to propagate information from [Logger] to
 * individual [Handler]s.
 */
class LogRecord {
  final Level level;
  final String message;

  /** Logger where this record is stored. */
  final String loggerName;

  /** Time when this record was created. */
  final DateTime time;

  /** Unique sequence number greater than all log records created before it. */
  final int sequenceNumber;

  static int _nextNumber = 0;

  /** Associated exception (if any) when recording errors messages. */
  Exception exception;

  /** Associated exception message (if any) when recording errors messages. */
  String exceptionText;

  LogRecord(
      this.level, this.message, this.loggerName,
      [time, this.exception, this.exceptionText]) :
    this.time = (time == null) ? new DateTime.now() : time,
    this.sequenceNumber = LogRecord._nextNumber++;
}
