// 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.

/**
 * Support for logging.
 *
 * For information on installing and importing this library, see the
 * [logging package on pub.dartlang.org]
 * (http://pub.dartlang.org/packages/logging).
 *
 * ## Initializing
 *
 * By default, the logging package does not do anything useful with the
 * log messages. You must configure the logging level and add a handler
 * for the log messages.
 *
 * Here is a simple logging configuration that logs all messages
 * via `print`.
 *
 *     Logger.root.level = Level.ALL;
 *     Logger.root.onRecord.listen((LogRecord rec) {
 *       print('${rec.level.name}: ${rec.time}: ${rec.message}');
 *     });
 *
 * First, set the root [Level]. All messages at or above the level are
 * sent to the [onRecord] stream.
 *
 * Then, listen on the [onRecord] stream for [LogRecord] events. The
 * [LogRecord] class has various properties for the message, error,
 * logger name, and more.
 *
 * ## Logging messages
 *
 * Create a [Logger] with a unique name to easily identify the source
 * of the log messages.
 *
 *     final Logger log = new Logger('MyClassName');
 *
 * Here is an example of logging a debug message and an error:
 *
 *     Future future = doSomethingAsync();
 *     future.then((result) {
 *       log.fine('Got the result: $result');
 *       processResult(result);
 *     })
 *     .catchError((e, stackTrace) => log.severe('Oh noes!', e, stackTrace));
 *
 * See the [Logger] class for the different logging methods.
 */
library logging;

import 'dart:async';
import 'package:unmodifiable_collection/unmodifiable_collection.dart';

/**
 * 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;

  final Map<String, Logger> _children;

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

  /** Controller used to notify when log entries are added to this logger. */
  StreamController<LogRecord> _controller;

  /**
   * 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) {
    return _loggers.putIfAbsent(name, () => new Logger._named(name));
  }

  factory Logger._named(String name) {
    if (name.startsWith('.')) {
      throw new ArgumentError("name shouldn't start with a '.'");
    }
    // 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);
    }
    return new Logger._internal(thisName, parent, new Map<String, Logger>());
  }

  Logger._internal(this.name, this.parent, Map<String, Logger> children) :
    this._children = children,
    this.children = new UnmodifiableMapView(children) {
    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. */
  void set level(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 stream of messages added to this [Logger]. You can listen for
   * messages using the standard stream APIs, for instance:
   *    logger.onRecord.listen((record) { ... });
   */
  Stream<LogRecord> get onRecord => _getStream();

  void clearListeners() {
    if (hierarchicalLoggingEnabled || parent == null) {
      if (_controller != null) {
        _controller.close();
        _controller = null;
      }
    } else {
      root.clearListeners();
    }
  }

  /** 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).
   */
  void log(Level logLevel, String message, [Object error,
                                            StackTrace stackTrace]) {
    if (isLoggable(logLevel)) {
      var record = new LogRecord(logLevel, message, fullName, error,
          stackTrace);

      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, [Object error, StackTrace stackTrace]) =>
      log(Level.FINEST, message, error, stackTrace);

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

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

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

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

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

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

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

  Stream<LogRecord> _getStream() {
    if (hierarchicalLoggingEnabled || parent == null) {
      if (_controller == null) {
        _controller = new StreamController<LogRecord>.broadcast(sync: true);
      }
      return _controller.stream;
    } else {
      return root._getStream();
    }
  }

  void _publish(LogRecord record) {
    if (_controller != null) {
      _controller.add(record);
    }
  }

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

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


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

/**
 * [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> {

  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 ==(Object other) => other is Level && 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 error (if any) when recording errors messages. */
  final Object error;

  /** Associated stackTrace (if any) when recording errors messages. */
  final StackTrace stackTrace;

  LogRecord(this.level, this.message, this.loggerName, [this.error,
                                                        this.stackTrace])
      : time = new DateTime.now(),
        sequenceNumber = LogRecord._nextNumber++;

  String toString() => '[${level.name}] $loggerName: $message';
}
