// Copyright 2013 The Flutter Authors. 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' show Timer, runZoned;
import 'dart:io' as io show
  IOSink,
  stderr,
  stdout;

import 'package:logging/logging.dart' as log;
import 'package:meta/meta.dart';

// This is where a flutter_tool style progress spinner, color output,
// ascii art, terminal control for clearing lines or the whole screen, etc.
// can go. We can just add more methods to Logger using the flutter_tool's
// Logger as a guide:
//
// https://github.com/flutter/flutter/blob/c530276f7806c77da2541c518a0e103c9bb44f10/packages/flutter_tools/lib/src/base/logger.dart#L422

/// A simplified wrapper around the [Logger] from package:logging.
///
/// The default log level is [Logger.status]. A --quiet flag might change it to
/// [Logger.warning] or [Logger.error]. A --verbose flag might change it to
/// [Logger.info].
///
/// Log messages at [Logger.warning] and higher will be written to stderr, and
/// to stdout otherwise. [Logger.test] records all log messages to a buffer,
/// which can be inspected by unit tetss.
class Logger {
  /// Constructs a logger for use in the tool.
  Logger() : _logger = log.Logger.detached('et'), _test = false {
    _logger.level = statusLevel;
    _logger.onRecord.listen(_handler);
    _setupIoSink(io.stderr);
    _setupIoSink(io.stdout);
  }

  /// A logger for tests.
  @visibleForTesting
  Logger.test() : _logger = log.Logger.detached('et'), _test = true {
    _logger.level = statusLevel;
    _logger.onRecord.listen((log.LogRecord r) => _testLogs.add(r));
  }

  /// The logging level for error messages. These go to stderr.
  static const log.Level errorLevel = log.Level('ERROR', 100);

  /// The logging level for warning messages. These go to stderr.
  static const log.Level warningLevel = log.Level('WARNING', 75);

  /// The logging level for normal status messages. These go to stdout.
  static const log.Level statusLevel = log.Level('STATUS', 25);

  /// The logging level for verbose informational messages. These go to stdout.
  static const log.Level infoLevel = log.Level('INFO', 10);

  static void _handler(log.LogRecord r) {
    final io.IOSink sink = r.level >= warningLevel ? io.stderr : io.stdout;
    final String prefix = r.level >= warningLevel
      ? '[${r.time}] ${r.level}: '
      : '';
    _ioSinkWrite(sink, '$prefix${r.message}');
  }

  // Status of the global io.stderr and io.stdout is shared across all
  // Logger instances.
  static bool _stdioDone = false;

  // stdout and stderr might already be closed, and when not already closed,
  // writing can still fail by throwing either a sync or async exception.
  // This function handles all three cases.
  static void _ioSinkWrite(io.IOSink sink, String message) {
    if (_stdioDone) {
      return;
    }
    runZoned<void>(() {
      try {
        sink.write(message);
      } catch (_) { // ignore: avoid_catches_without_on_clauses
        _stdioDone = true;
      }
    }, onError: (Object e, StackTrace s) {
      _stdioDone = true;
    });
  }

  static void _setupIoSink(io.IOSink sink) {
    sink.done.then(
      (void _) { _stdioDone = true; },
      onError: (Object err, StackTrace st) { _stdioDone = true; },
    );
  }

  final log.Logger _logger;
  final List<log.LogRecord> _testLogs = <log.LogRecord>[];
  final bool _test;

  Spinner? _status;

  /// Get the current logging level.
  log.Level get level => _logger.level;

  /// Set the current logging level.
  set level(log.Level l) {
    _logger.level = l;
  }

  /// Record a log message at level [Logger.error].
  void error(
    Object? message, {
    int indent = 0,
    bool newline = true,
    bool fit = false,
  }) {
    _emitLog(errorLevel, message, indent, newline, fit);
  }

  /// Record a log message at level [Logger.warning].
  void warning(
    Object? message, {
    int indent = 0,
    bool newline = true,
    bool fit = false,
  }) {
    _emitLog(warningLevel, message, indent, newline, fit);
  }

  /// Record a log message at level [Logger.warning].
  void status(
    Object? message, {
    int indent = 0,
    bool newline = true,
    bool fit = false,
  }) {
    _emitLog(statusLevel, message, indent, newline, fit);
  }

  /// Record a log message at level [Logger.info].
  void info(
    Object? message, {
    int indent = 0,
    bool newline = true,
    bool fit = false,
  }) {
    _emitLog(infoLevel, message, indent, newline, fit);
  }

  /// Writes a number of spaces to stdout equal to the width of the terminal
  /// and emits a carriage return.
  void clearLine() {
    if (!io.stdout.hasTerminal || _test) {
      return;
    }
    _status?.pause();
    _emitClearLine();
    _status?.resume();
  }

  /// Starts printing a progress spinner.
  Spinner startSpinner({
    void Function()? onFinish,
  }) {
    void finishCallback() {
      onFinish?.call();
      _status = null;
    }
    _status = io.stdout.hasTerminal && !_test
      ? FlutterSpinner(onFinish: finishCallback)
      : Spinner(onFinish: finishCallback);
    _status!.start();
    return _status!;
  }

  static void _emitClearLine() {
    if (io.stdout.supportsAnsiEscapes) {
      // Go to start of the line and clear the line.
      _ioSinkWrite(io.stdout, '\r\x1B[K');
      return;
    }
    final int width = io.stdout.terminalColumns;
    final String backspaces = '\b' * width;
    final String spaces = ' ' * width;
    _ioSinkWrite(io.stdout, '$backspaces$spaces$backspaces');
  }

  void _emitLog(
    log.Level level,
    Object? message,
    int indent,
    bool newline,
    bool fit,
  ) {
    String m = '${' ' * indent}$message${newline ? '\n' : ''}';
    if (fit && io.stdout.hasTerminal) {
      m = fitToWidth(m, io.stdout.terminalColumns);
    }
    _status?.pause();
    _logger.log(level, m);
    _status?.resume();
  }

  /// Shorten a string such that its length will be `w` by replacing
  /// enough characters in the middle with '...'. Trailing whitespace will not
  /// be preserved or counted against 'w', but if the input ends with a newline,
  /// then the output will end with a newline that is not counted against 'w'.
  /// That is, if the input string ends with a newline, the output string will
  /// have length up to (w + 1) and end with a newline.
  ///
  /// If w <= 0, the result will be the empty string.
  /// If w <= 3, the result will be a string containing w '.'s.
  /// If there are a different number of non-'...' characters to the right and
  /// left of '...' in the result, then the right will have one more than the
  /// left.
  @visibleForTesting
  static String fitToWidth(String s, int w) {
    // Preserve a trailing newline if needed.
    final String maybeNewline = s.endsWith('\n') ? '\n' : '';
    if (w <= 0) {
      return maybeNewline;
    }
    if (w <= 3) {
      return '${'.' * w}$maybeNewline';
    }

    // But remove trailing whitespace before removing the middle of the string.
    s = s.trimRight();
    if (s.length <= w) {
      return '$s$maybeNewline';
    }

    // remove (s.length + 3 - w) characters from the middle of `s` and
    // replace them with '...'.
    final int diff = (s.length + 3) - w;
    final int leftEnd = (s.length - diff) ~/ 2;
    final int rightStart = (s.length + diff) ~/ 2;
    s = s.replaceRange(leftEnd, rightStart, '...');
    return s + maybeNewline;
  }

  /// In a [Logger] constructed by [Logger.test], this list will contain all of
  /// the [LogRecord]s emitted by the test.
  @visibleForTesting
  List<log.LogRecord> get testLogs => _testLogs;
}


/// A base class for progress spinners, and a no-op implementation that prints
/// nothing.
class Spinner {
  /// Creates a progress spinner. If supplied the `onDone` callback will be
  /// called when `finish()` is called.
  Spinner({
    this.onFinish,
  });

  /// The callback called when `finish()` is called.
  final void Function()? onFinish;

  /// Starts the spinner animation.
  void start() {}

  /// Pauses the spinner animation. That is, this call causes printing to the
  /// terminal to stop.
  void pause() {}

  /// Resumes the animation at the same from where `pause()` was called.
  void resume() {}

  /// Ends an animation, calling the `onFinish` callback if one was provided.
  void finish() {
    onFinish?.call();
  }
}

/// A [Spinner] implementation that prints an animated "Flutter" banner.
class FlutterSpinner extends Spinner {
  // ignore: public_member_api_docs
  FlutterSpinner({
    super.onFinish,
  });

  @visibleForTesting
  /// The frames of the animation.
  static const String frames = '⢸⡯⠭⠅⢸⣇⣀⡀⢸⣇⣸⡇⠈⢹⡏⠁⠈⢹⡏⠁⢸⣯⣭⡅⢸⡯⢕⡂⠀⠀';

  static final List<String> _flutterAnimation = frames
      .runes
      .map<String>((int scalar) => String.fromCharCode(scalar))
      .toList();

  Timer? _timer;
  int _ticks = 0;
  int _lastAnimationFrameLength = 0;

  @override
  void start() {
    _startSpinner();
  }

  void _startSpinner() {
    _timer = Timer.periodic(const Duration(milliseconds: 100), _callback);
    _callback(_timer!);
  }

  void _callback(Timer timer) {
    Logger._ioSinkWrite(io.stdout, '\b' * _lastAnimationFrameLength);
    _ticks += 1;
    final String newFrame = _currentAnimationFrame;
    _lastAnimationFrameLength = newFrame.runes.length;
    Logger._ioSinkWrite(io.stdout, newFrame);
  }

  String get _currentAnimationFrame {
    return _flutterAnimation[_ticks % _flutterAnimation.length];
  }

  @override
  void pause() {
    Logger._emitClearLine();
    _lastAnimationFrameLength = 0;
    _timer?.cancel();
  }

  @override
  void resume() {
    _startSpinner();
  }

  @override
  void finish() {
    _timer?.cancel();
    _timer = null;
    Logger._emitClearLine();
    _lastAnimationFrameLength = 0;
    if (onFinish != null) {
      onFinish!();
    }
  }
}
