// 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 = 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 (!canAnimateOutput ||
        !log.verbosity.isLevelVisible(level) ||
        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 = Timer.periodic(Duration(milliseconds: 100), (_) {
      _update();
    });

    stdout.write('$_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();
  }

  /// Erases the progress message and stops the progress indicator.
  Future<void> stopAndClear() async {
    _stopwatch.stop();

    if (_timer != null) {
      stdout.write('\b' * (_message.length + '... '.length + _timeLength));
    }

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

  /// 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));
  }
}
