// Copyright (c) 2019, 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.

import 'dart:async';
import 'dart:collection';

import 'level.dart';
import 'log_record.dart';

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

/// Automatically record stack traces for any message of this level or above.
///
/// Because this is expensive, this is off by default.
Level recordStackTraceAtLevel = Level.OFF;

/// The default [Level].
const defaultLevel = 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?.name.isNotEmpty ?? false ? '${parent!.fullName}.$name' : name;

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

  /// Logging [Level] used for entries generated on this logger.
  ///
  /// Only the root logger is guaranteed to have a non-null [Level].
  Level? _level;

  /// Private modifiable map of child loggers, indexed by their simple names.
  final Map<String, Logger> _children;

  /// Children in the hierarchy of loggers, indexed by their simple names.
  ///
  /// This is an unmodifiable map.
  final Map<String, Logger> children;

  /// Controller used to notify when log entries are added to this logger.
  ///
  /// If hierarchical logging is disabled then this is `null` for all but the
  /// root [Logger].
  StreamController<LogRecord>? _controller;

  /// Controller used to notify when the log level of this logger is changed.
  StreamController<Level?>? _levelChangedController;

  /// Create or find a Logger by name.
  ///
  /// Calling `Logger(name)` will return the same instance whenever it is called
  /// with the same string name. Loggers created with this constructor are
  /// retained indefinitely and available through [attachedLoggers].
  factory Logger(String name) =>
      _loggers.putIfAbsent(name, () => Logger._named(name));

  /// Creates a new detached [Logger].
  ///
  /// Returns a new [Logger] instance (unlike `new Logger`, which returns a
  /// [Logger] singleton), which doesn't have any parent or children,
  /// and is not a part of the global hierarchical loggers structure.
  ///
  /// It can be useful when you just need a local short-living logger,
  /// which you'd like to be garbage-collected later.
  factory Logger.detached(String name) =>
      Logger._internal(name, null, <String, Logger>{});

  factory Logger._named(String name) {
    if (name.startsWith('.')) {
      throw ArgumentError("name shouldn't start with a '.'");
    }
    if (name.endsWith('.')) {
      throw ArgumentError("name shouldn't end with a '.'");
    }

    // Split hierarchical names (separated with '.').
    final dot = name.lastIndexOf('.');
    Logger? parent;
    String thisName;
    if (dot == -1) {
      if (name != '') parent = Logger('');
      thisName = name;
    } else {
      parent = Logger(name.substring(0, dot));
      thisName = name.substring(dot + 1);
    }
    return Logger._internal(thisName, parent, <String, Logger>{});
  }

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

  /// Effective level considering the levels established in this logger's
  /// parents (when [hierarchicalLoggingEnabled] is true).
  Level get level {
    Level effectiveLevel;

    if (parent == null) {
      // We're either the root logger or a detached logger.  Return our own
      // level.
      effectiveLevel = _level!;
    } else if (!hierarchicalLoggingEnabled) {
      effectiveLevel = root._level!;
    } else {
      effectiveLevel = _level ?? parent!.level;
    }

    // ignore: unnecessary_null_comparison
    assert(effectiveLevel != null);
    return effectiveLevel;
  }

  /// Override the level for this particular [Logger] and its children.
  ///
  /// Setting this to `null` makes it inherit the [parent]s level.
  set level(Level? value) {
    if (!hierarchicalLoggingEnabled && parent != null) {
      throw UnsupportedError(
        'Please set "hierarchicalLoggingEnabled" to true if you want to '
        'change the level on a non-root logger.',
      );
    }
    if (parent == null && value == null) {
      throw UnsupportedError(
        'Cannot set the level to `null` on a logger with no parent.',
      );
    }
    final isLevelChanged = _level != value;
    _level = value;
    if (isLevelChanged) {
      _levelChangedController?.add(value);
    }
  }

  /// Returns a stream of level values set to this [Logger].
  ///
  /// You can listen for set levels using the standard stream APIs,
  /// for instance:
  ///
  /// ```dart
  /// logger.onLevelChanged.listen((level) { ... });
  /// ```
  /// A state error will be thrown if the level is changed
  /// inside the callback.
  Stream<Level?> get onLevelChanged {
    _levelChangedController ??= StreamController<Level?>.broadcast(sync: true);
    return _levelChangedController!.stream;
  }

  /// Returns a stream of messages added to this [Logger].
  ///
  /// You can listen for messages using the standard stream APIs, for instance:
  ///
  /// ```dart
  /// logger.onRecord.listen((record) { ... });
  /// ```
  Stream<LogRecord> get onRecord => _getStream();

  void clearListeners() {
    if (hierarchicalLoggingEnabled || parent == 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).
  ///
  /// If [message] is a [Function], it will be lazy evaluated. Additionally, if
  /// [message] or its evaluated value is not a [String], then 'toString()' will
  /// be called on the object and the result will be logged. The log record will
  /// contain a field holding the original object.
  ///
  /// The log record will also contain a field for the zone in which this call
  /// was made. This can be advantageous if a log listener wants to handler
  /// records of different zones differently (e.g. group log records by HTTP
  /// request if each HTTP request handler runs in it's own zone).
  ///
  /// If this record is logged at a level equal to or higher than
  /// [recordStackTraceAtLevel] and [stackTrace] is `null` or [StackTrace.empty]
  /// it will be defaulted to the current stack trace for this call.
  void log(
    Level logLevel,
    Object? message, [
    Object? error,
    StackTrace? stackTrace,
    Zone? zone,
  ]) {
    Object? object;
    if (isLoggable(logLevel)) {
      if (message is Function) {
        message = (message as Object? Function())();
      }

      String msg;
      if (message is String) {
        msg = message;
      } else {
        msg = message.toString();
        object = message;
      }

      if ((stackTrace == null || stackTrace == StackTrace.empty) &&
          logLevel >= recordStackTraceAtLevel) {
        stackTrace = StackTrace.current;
        error ??= 'autogenerated stack trace for $logLevel $msg';
      }
      zone ??= Zone.current;

      final record = LogRecord(
        logLevel,
        msg,
        fullName,
        error,
        stackTrace,
        zone,
        object,
      );

      if (parent == null) {
        _publish(record);
      } else if (!hierarchicalLoggingEnabled) {
        root._publish(record);
      } else {
        Logger? target = this;
        while (target != null) {
          target._publish(record);
          target = target.parent;
        }
      }
    }
  }

  /// Log message at level [Level.FINEST].
  ///
  /// See [log] for information on how non-String [message] arguments are
  /// handled.
  void finest(Object? message, [Object? error, StackTrace? stackTrace]) =>
      log(Level.FINEST, message, error, stackTrace);

  /// Log message at level [Level.FINER].
  ///
  /// See [log] for information on how non-String [message] arguments are
  /// handled.
  void finer(Object? message, [Object? error, StackTrace? stackTrace]) =>
      log(Level.FINER, message, error, stackTrace);

  /// Log message at level [Level.FINE].
  ///
  /// See [log] for information on how non-String [message] arguments are
  /// handled.
  void fine(Object? message, [Object? error, StackTrace? stackTrace]) =>
      log(Level.FINE, message, error, stackTrace);

  /// Log message at level [Level.CONFIG].
  ///
  /// See [log] for information on how non-String [message] arguments are
  /// handled.
  void config(Object? message, [Object? error, StackTrace? stackTrace]) =>
      log(Level.CONFIG, message, error, stackTrace);

  /// Log message at level [Level.INFO].
  ///
  /// See [log] for information on how non-String [message] arguments are
  /// handled.
  void info(Object? message, [Object? error, StackTrace? stackTrace]) =>
      log(Level.INFO, message, error, stackTrace);

  /// Log message at level [Level.WARNING].
  ///
  /// See [log] for information on how non-String [message] arguments are
  /// handled.
  void warning(Object? message, [Object? error, StackTrace? stackTrace]) =>
      log(Level.WARNING, message, error, stackTrace);

  /// Log message at level [Level.SEVERE].
  ///
  /// See [log] for information on how non-String [message] arguments are
  /// handled.
  void severe(Object? message, [Object? error, StackTrace? stackTrace]) =>
      log(Level.SEVERE, message, error, stackTrace);

  /// Log message at level [Level.SHOUT].
  ///
  /// See [log] for information on how non-String [message] arguments are
  /// handled.
  void shout(Object? message, [Object? error, StackTrace? stackTrace]) =>
      log(Level.SHOUT, message, error, stackTrace);

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

  void _publish(LogRecord record) => _controller?.add(record);

  /// Top-level root [Logger].
  static final Logger root = Logger('');

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

  /// All attached [Logger]s in the system.
  ///
  /// Loggers created with [Logger.detached] are not included.
  static Iterable<Logger> get attachedLoggers => _loggers.values;
}
