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

import 'dart:async';
import 'dart:io';

import 'log.dart' as log;
import 'utils.dart';

/// A live-updating progress indicator for long-running log entries.
class Progress {
  /// The timer used to write "..." during a progress log.
  Timer _timer;

  /// The [Stopwatch] used to track how long a progress log has been running.
  final _stopwatch = new Stopwatch();

  /// The progress message as it's being incrementally appended.
  ///
  /// When the progress is done, a single entry will be added to the log for it.
  final String _message;

  /// Gets the current progress time as a parenthesized, formatted string.
  String get _time => "(${niceDuration(_stopwatch.elapsed)})";

  /// The length of the most recently-printed [_time] string.
  var _timeLength = 0;

  /// Creates a new progress indicator.
  ///
  /// If [fine] is passed, this will log progress messages on [log.Level.FINE]
  /// as opposed to [log.Level.MESSAGE].
  Progress(this._message, {bool fine: false}) {
    _stopwatch.start();

    var level = fine ? log.Level.FINE : log.Level.MESSAGE;

    // The animation is only shown when it would be meaningful to a human.
    // That means we're writing a visible message to a TTY at normal log levels
    // with non-JSON output.
    if (stdioType(stdout) != StdioType.TERMINAL ||
        !log.verbosity.isLevelVisible(level) ||
        log.json.enabled ||
        fine ||
        log.verbosity.isLevelVisible(log.Level.FINE)) {
      // Not animating, so just log the start and wait until the task is
      // completed.
      log.write(level, "$_message...");
      return;
    }

    _timer = new Timer.periodic(new Duration(milliseconds: 100), (_) {
      _update();
    });

    stdout.write(log.format("$_message... "));
  }

  /// Stops the progress indicator.
  void stop() {
    _stopwatch.stop();

    // Always log the final time as [log.fine] because for the most part normal
    // users don't care about the precise time information beyond what's shown
    // in the animation.
    log.fine("$_message finished $_time.");

    // If we were animating, print one final update to show the user the final
    // time.
    if (_timer == null) return;
    _timer.cancel();
    _timer = null;
    _update();
    stdout.writeln();
  }

  /// Stop animating the progress indicator.
  ///
  /// This will continue running the stopwatch so that the full time can be
  /// logged in [stop].
  void stopAnimating() {
    if (_timer == null) return;

    // Erase the time indicator so that we don't leave a misleading
    // half-complete time indicator on the console.
    stdout.writeln("\b" * _timeLength);
    _timeLength = 0;
    _timer.cancel();
    _timer = null;
  }

  /// Refreshes the progress line.
  void _update() {
    if (log.isMuted) return;

    // Show the time only once it gets noticeably long.
    if (_stopwatch.elapsed.inSeconds == 0) return;

    // Erase the last time that was printed. Erasing just the time using `\b`
    // rather than using `\r` to erase the entire line ensures that we don't
    // spam progress lines if they're wider than the terminal width.
    stdout.write("\b" * _timeLength);
    var time = _time;
    _timeLength = time.length;
    stdout.write(log.gray(time));
  }
}
