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