// Copyright 2014 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:io' as io;

import 'package:meta/meta.dart';

/// An interface for presenting text output to the user.
///
/// Although this could have been simplified by calling `print()`
/// from the tool, this abstraction allows unit tests to verify output
/// and allows a GUI frontend to provide an alternative implementation.
///
/// User input probably should be part of this class–however it is currently
/// part of context.dart.
abstract class Stdio {
  final List<String> logs = <String>[];

  /// Error messages printed to STDERR.
  ///
  /// Display an error `message` to the user on stderr. Print errors if the code
  /// fails in some way. Errors are typically followed shortly by exiting the
  /// app with a non-zero exit status.
  @mustCallSuper
  void printError(String message) {
    logs.add('[error] $message');
  }

  /// Warning messages printed to STDERR.
  ///
  /// Display a warning `message` to the user on stderr. Print warnings if there
  /// is important information to convey to the user that is not fatal.
  @mustCallSuper
  void printWarning(String message) {
    logs.add('[warning] $message');
  }

  /// Ordinary STDOUT messages.
  ///
  /// Displays normal output on stdout. This should be used for things like
  /// progress messages, success messages, or just normal command output.
  @mustCallSuper
  void printStatus(String message) {
    logs.add('[status] $message');
  }

  /// Debug messages that are only printed in verbose mode.
  ///
  /// Use this for verbose tracing output. Users can turn this output on in order
  /// to help diagnose issues.
  @mustCallSuper
  void printTrace(String message) {
    logs.add('[trace] $message');
  }

  /// Write the `message` string to STDOUT without a trailing newline.
  @mustCallSuper
  void write(String message) {
    logs.add('[write] $message');
  }

  /// Read a line of text from STDIN.
  String readLineSync();
}

/// A logger that will print out trace messages.
class VerboseStdio extends Stdio {
  VerboseStdio({
    required this.stdout,
    required this.stderr,
    required this.stdin,
    this.filter,
  });

  factory VerboseStdio.local() => VerboseStdio(
        stdout: io.stdout,
        stderr: io.stderr,
        stdin: io.stdin,
      );

  final io.Stdout stdout;
  final io.Stdout stderr;
  final io.Stdin stdin;

  /// If provided, all messages will be passed through this function before being logged.
  final String Function(String)? filter;

  @override
  void printError(String message) {
    if (filter != null) {
      message = filter!(message);
    }
    super.printError(message);
    stderr.writeln(message);
  }

  @override
  void printWarning(String message) {
    if (filter != null) {
      message = filter!(message);
    }
    super.printWarning(message);
    stderr.writeln(message);
  }

  @override
  void printStatus(String message) {
    if (filter != null) {
      message = filter!(message);
    }
    super.printStatus(message);
    stdout.writeln(message);
  }

  @override
  void printTrace(String message) {
    if (filter != null) {
      message = filter!(message);
    }
    super.printTrace(message);
    stdout.writeln(message);
  }

  @override
  void write(String message) {
    if (filter != null) {
      message = filter!(message);
    }
    super.write(message);
    stdout.write(message);
  }

  @override
  String readLineSync() {
    return stdin.readLineSync()!;
  }
}
