// 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 analyzer.src.generated.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 = '';
  }
}
