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

library engine.incremental_logger;

/**
 * The shared instance of [Logger] used by several incremental resolution
 * classes. It is initialized externally by the Analysis Engine client.
 */
Logger logger = NULL_LOGGER;

/**
 * An instance of [Logger] that does not print anything.
 */
final Logger NULL_LOGGER = new _NullLogger();

/**
 * An instance of [Logger] that uses `print` for output.
 */
final Logger PRINT_LOGGER = new StringSinkLogger(new _PrintStringSink());

/**
 * A simple hierarchical logger.
 */
abstract class Logger {
  /**
   * Mark an enter to a new section with the given [name].
   */
  void enter(String name);

  /**
   * Mark an exit from the current sections, logs the duration.
   */
  void exit();

  /**
   * Logs the given [obj].
   */
  void log(Object obj);

  /**
   * Starts a new timer.
   */
  LoggingTimer startTimer();
}

/**
 * The handle of a timer.
 */
class LoggingTimer {
  final Logger _logger;
  final Stopwatch _stopwatch = new Stopwatch();

  LoggingTimer(this._logger) {
    _stopwatch.start();
  }

  /**
   * This methods stop the timer and logs the elapsed time.
   */
  void stop(String message) {
    _stopwatch.stop();
    _logger.log('$message in ${_stopwatch.elapsedMilliseconds} ms');
  }
}

/**
 * A [Logger] that writes to a [StringSink].
 */
class StringSinkLogger implements Logger {
  static const int _MAX_LINE_LENGTH = 512;
  final StringSink _sink;
  final List<_LoggerSection> _sectionStack = <_LoggerSection>[];
  _LoggerSection _section = new _LoggerSection('', 'ROOT');

  StringSinkLogger(this._sink);

  @override
  void enter(String name) {
    log('+++ $name');
    _sectionStack.add(_section);
    _section = new _LoggerSection(_section.indent + '\t', name);
  }

  @override
  void exit() {
    DateTime now = new DateTime.now();
    Duration duration = now.difference(_section.start);
    String message = '--- ${_section.name} in ${duration.inMilliseconds} ms';
    _section = _sectionStack.removeLast();
    log(message);
  }

  @override
  void log(Object obj) {
    DateTime now = new DateTime.now();
    String indent = _section.indent;
    String objStr = _getObjectString(obj);
    String line = '[$now] $indent$objStr';
    _sink.writeln(line);
  }

  @override
  LoggingTimer startTimer() {
    return new LoggingTimer(this);
  }

  String _getObjectString(Object obj) {
    if (obj == null) {
      return 'null';
    }
    if (obj is Function) {
      obj = obj();
    }
    String str = obj.toString();
    if (str.length < _MAX_LINE_LENGTH) {
      return str;
    }
    return str.split('\n').map((String line) {
      if (line.length > _MAX_LINE_LENGTH) {
        line = line.substring(0, _MAX_LINE_LENGTH) + '...';
      }
      return line;
    }).join('\n');
  }
}

class _LoggerSection {
  final DateTime start = new DateTime.now();
  final String indent;
  final String name;
  _LoggerSection(this.indent, this.name);
}

/**
 * A [Logger] that does nothing.
 */
class _NullLogger implements Logger {
  @override
  void enter(String name) {}

  @override
  void exit() {}

  @override
  void log(Object obj) {}

  @override
  LoggingTimer startTimer() {
    return new LoggingTimer(this);
  }
}

/**
 * A [StringSink] implementation that uses `print`.
 */
class _PrintStringSink implements StringSink {
  String _line = '';

  @override
  void write(Object obj) {
    if (obj == null) {
      _line += 'null';
    } else {
      _line += obj.toString();
    }
  }

  @override
  void writeAll(Iterable objects, [String separator = '']) {
    _line += objects.join(separator);
  }

  @override
  void writeCharCode(int charCode) {
    _line += new String.fromCharCode(charCode);
  }

  @override
  void writeln([Object obj = '']) {
    _line += obj;
    print(_line);
    _line = '';
  }
}
