// Copyright (c) 2013, 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.

part of dart.io;

// These match enum StdioHandleType in file.h
const int _stdioHandleTypeTerminal = 0;
const int _stdioHandleTypePipe = 1;
const int _stdioHandleTypeFile = 2;
const int _stdioHandleTypeSocket = 3;
const int _stdioHandleTypeOther = 4;
const int _stdioHandleTypeError = 5;

class _StdStream extends Stream<List<int>> {
  final Stream<List<int>> _stream;

  _StdStream(this._stream);

  StreamSubscription<List<int>> listen(
    void onData(List<int> event)?, {
    Function? onError,
    void onDone()?,
    bool? cancelOnError,
  }) {
    return _stream.listen(
      onData,
      onError: onError,
      onDone: onDone,
      cancelOnError: cancelOnError,
    );
  }
}

/// The standard input stream of the process.
///
/// Allows both synchronous and asynchronous reads from the standard
/// input stream.
///
/// Mixing synchronous and asynchronous reads is undefined.
class Stdin extends _StdStream implements Stream<List<int>> {
  int _fd;

  Stdin._(Stream<List<int>> stream, this._fd) : super(stream);

  /// Reads a line from stdin.
  ///
  /// Blocks until a full line is available.
  ///
  /// Lines may be terminated by either `<CR><LF>` or `<LF>`. On Windows,
  /// in cases where the [stdioType] of stdin is [StdioType.terminal],
  /// the terminator may also be a single `<CR>`.
  ///
  /// Input bytes are converted to a string by [encoding].
  /// If [encoding] is omitted, it defaults to [systemEncoding].
  ///
  /// If [retainNewlines] is `false`, the returned string will not include the
  /// final line terminator. If `true`, the returned string will include the line
  /// terminator. Default is `false`.
  ///
  /// If end-of-file is reached after any bytes have been read from stdin,
  /// that data is returned without a line terminator.
  /// Returns `null` if no bytes preceded the end of input.
  String? readLineSync({
    Encoding encoding = systemEncoding,
    bool retainNewlines = false,
  }) {
    const CR = 13;
    const LF = 10;
    final List<int> line = <int>[];
    // On Windows, if lineMode is disabled, only CR is received.
    bool crIsNewline =
        Platform.isWindows &&
        (stdioType(stdin) == StdioType.terminal) &&
        !lineMode;
    if (retainNewlines) {
      int byte;
      do {
        byte = readByteSync();
        if (byte < 0) {
          break;
        }
        line.add(byte);
      } while (byte != LF && !(byte == CR && crIsNewline));
      if (line.isEmpty) {
        return null;
      }
    } else if (crIsNewline) {
      // CR and LF are both line terminators, neither is retained.
      while (true) {
        int byte = readByteSync();
        if (byte < 0) {
          if (line.isEmpty) return null;
          break;
        }
        if (byte == LF || byte == CR) break;
        line.add(byte);
      }
    } else {
      // Case having to handle CR LF as a single unretained line terminator.
      outer:
      while (true) {
        int byte = readByteSync();
        if (byte == LF) break;
        if (byte == CR) {
          do {
            byte = readByteSync();
            if (byte == LF) break outer;

            line.add(CR);
          } while (byte == CR);
          // Fall through and handle non-CR character.
        }
        if (byte < 0) {
          if (line.isEmpty) return null;
          break;
        }
        line.add(byte);
      }
    }
    return encoding.decode(line);
  }

  /// Whether echo mode is enabled on [stdin].
  ///
  /// If disabled, input from the console will not be echoed.
  ///
  /// Default depends on the parent process, but is usually enabled.
  ///
  /// On POSIX systems this mode is the `echo` local terminal mode. Before
  /// Dart 2.18, it also controlled the `echonl` mode, which is now controlled
  /// by [echoNewlineMode].
  ///
  /// On Windows this mode can only be enabled if [lineMode] is enabled as well.
  external bool get echoMode;
  external set echoMode(bool echoMode);

  /// Whether echo newline mode is enabled on [stdin].
  ///
  /// If enabled, newlines from the terminal will be echoed even if the regular
  /// [echoMode] is disabled. This mode may require `lineMode` to be turned on
  /// to have an effect.
  ///
  /// Default depends on the parent process, but is usually disabled.
  ///
  /// On POSIX systems this mode is the `echonl` local terminal mode.
  ///
  /// On Windows this mode cannot be set.
  @Since("2.18")
  external bool get echoNewlineMode;
  @Since("2.18")
  external set echoNewlineMode(bool echoNewlineMode);

  /// Whether line mode is enabled on [stdin].
  ///
  /// If enabled, characters are delayed until a newline character is entered.
  /// If disabled, characters will be available as typed.
  ///
  /// Default depends on the parent process, but is usually enabled.
  ///
  /// On POSIX systems this mode is the `icanon` local terminal mode.
  ///
  /// On Windows this mode can only be disabled if [echoMode] is disabled as
  /// well.
  external bool get lineMode;
  external set lineMode(bool lineMode);

  /// Whether connected to a terminal that supports ANSI escape sequences.
  ///
  /// Not all terminals are recognized, and not all recognized terminals can
  /// report whether they support ANSI escape sequences, so this value is a
  /// best-effort attempt at detecting the support.
  ///
  /// The actual escape sequence support may differ between terminals,
  /// with some terminals supporting more escape sequences than others,
  /// and some terminals even differing in behavior for the same escape
  /// sequence.
  ///
  /// The ANSI color selection is generally supported.
  ///
  /// Currently, a `TERM` environment variable containing the string `xterm`
  /// will be taken as evidence that ANSI escape sequences are supported.
  /// On Windows, only versions of Windows 10 after v.1511
  /// ("TH2", OS build 10586) will be detected as supporting the output of
  /// ANSI escape sequences, and only versions after v.1607 ("Anniversary
  /// Update", OS build 14393) will be detected as supporting the input of
  /// ANSI escape sequences.
  external bool get supportsAnsiEscapes;

  /// Synchronously reads a byte from stdin.
  ///
  /// This call will block until a byte is available.
  ///
  /// If at end of file, -1 is returned.
  external int readByteSync();

  /// Whether there is a terminal attached to stdin.
  bool get hasTerminal {
    try {
      return stdioType(this) == StdioType.terminal;
    } on FileSystemException catch (_) {
      // If stdioType throws a FileSystemException, then it is not hooked up to
      // a terminal, probably because it is closed, but let other exception
      // types bubble up.
      return false;
    }
  }
}

/// An [IOSink] connected to either the standard out or error of the process.
///
/// Provides a *blocking* `IOSink`, so using it to write will block until
/// the output is written.
///
/// In some situations this blocking behavior is undesirable as it does not
/// provide the same non-blocking behavior that `dart:io` in general exposes.
/// Use the property [nonBlocking] to get an [IOSink] which has the non-blocking
/// behavior.
///
/// This class can also be used to check whether `stdout` or `stderr` is
/// connected to a terminal and query some terminal properties.
///
/// The [addError] API is inherited from [StreamSink] and calling it will result
/// in an unhandled asynchronous error unless there is an error handler on
/// [done].
///
/// The [lineTerminator] field is used by the [write], [writeln], [writeAll]
/// and [writeCharCode] methods to translate `"\n"`. By default, `"\n"` is
/// output literally.
class Stdout extends _StdSink implements IOSink {
  final int _fd;
  IOSink? _nonBlocking;

  Stdout._(IOSink sink, this._fd) : super(sink);

  /// Whether there is a terminal attached to stdout.
  bool get hasTerminal => _hasTerminal(_fd);

  /// The number of columns of the terminal.
  ///
  /// If no terminal is attached to stdout, a [StdoutException] is thrown. See
  /// [hasTerminal] for more info.
  int get terminalColumns => _terminalColumns(_fd);

  /// The number of lines of the terminal.
  ///
  /// If no terminal is attached to stdout, a [StdoutException] is thrown. See
  /// [hasTerminal] for more info.
  int get terminalLines => _terminalLines(_fd);

  /// Whether connected to a terminal that supports ANSI escape sequences.
  ///
  /// Not all terminals are recognized, and not all recognized terminals can
  /// report whether they support ANSI escape sequences, so this value is a
  /// best-effort attempt at detecting the support.
  ///
  /// The actual escape sequence support may differ between terminals,
  /// with some terminals supporting more escape sequences than others,
  /// and some terminals even differing in behavior for the same escape
  /// sequence.
  ///
  /// The ANSI color selection is generally supported.
  ///
  /// Currently, a `TERM` environment variable containing the string `xterm`
  /// will be taken as evidence that ANSI escape sequences are supported.
  /// On Windows, only versions of Windows 10 after v.1511
  /// ("TH2", OS build 10586) will be detected as supporting the output of
  /// ANSI escape sequences, and only versions after v.1607 ("Anniversary
  /// Update", OS build 14393) will be detected as supporting the input of
  /// ANSI escape sequences.
  bool get supportsAnsiEscapes => _supportsAnsiEscapes(_fd);

  external bool _hasTerminal(int fd);
  external int _terminalColumns(int fd);
  external int _terminalLines(int fd);
  external static bool _supportsAnsiEscapes(int fd);

  /// A non-blocking `IOSink` for the same output.
  ///
  /// The returned `IOSink` will be initialized with an [encoding] of UTF-8 and
  /// will not do line ending conversion.
  IOSink get nonBlocking {
    return _nonBlocking ??= new IOSink(new _FileStreamConsumer.fromStdio(_fd));
  }
}

/// Exception thrown by some operations of [Stdout]
class StdoutException implements IOException {
  /// Message describing cause of the exception.
  final String message;

  /// The underlying OS error, if available.
  final OSError? osError;

  const StdoutException(this.message, [this.osError]);

  String toString() {
    return "StdoutException: $message${osError == null ? "" : ", $osError"}";
  }
}

/// Exception thrown by some operations of [Stdin]
class StdinException implements IOException {
  /// Message describing cause of the exception.
  final String message;

  /// The underlying OS error, if available.
  final OSError? osError;

  const StdinException(this.message, [this.osError]);

  String toString() {
    return "StdinException: $message${osError == null ? "" : ", $osError"}";
  }
}

class _StdConsumer implements StreamConsumer<List<int>> {
  final RandomAccessFile _file;

  _StdConsumer(int fd) : _file = _File._openStdioSync(fd);

  Future addStream(Stream<List<int>> stream) {
    var completer = new Completer();
    late StreamSubscription<List<int>> sub;
    sub = stream.listen(
      (data) {
        try {
          _file.writeFromSync(data);
        } catch (e, s) {
          sub.cancel();
          completer.completeError(e, s);
        }
      },
      onError: completer.completeError,
      onDone: completer.complete,
      cancelOnError: true,
    );
    return completer.future;
  }

  Future close() {
    _file.closeSync();
    return new Future.value();
  }
}

/// Pattern matching a "\n" character not following a "\r".
///
/// Used to replace such with "\r\n" in the [_StdSink] write methods.
final _newLineDetector = RegExp(r'(?<!\r)\n');

/// Pattern matching "\n" characters not following a "\r", or at the start of
/// input.
///
/// Used to replace those with "\r\n" in the [_StdSink] write methods,
/// when the previously written string ended in a \r character.
final _newLineDetectorAfterCR = RegExp(r'(?<!\r|^)\n');

class _StdSink implements IOSink {
  final IOSink _sink;
  bool _windowsLineTerminator = false;
  bool _lastWrittenCharIsCR = false;

  _StdSink(this._sink);

  /// Line ending appended by [writeln], and replacing `"\n"` in some methods.
  ///
  /// Must be one of the values `"\n"` (the default) or `"\r\n"`.
  ///
  /// When set to `"\r\n"`, the methods [write], [writeln], [writeAll] and
  /// [writeCharCode] will convert embedded newlines, `"\n"`, in their
  /// arguments to `"\r\n"`. If their arguments already contain `"\r\n"`
  /// sequences, then these sequences will be not be converted. This is true
  /// even if the sequence is generated across different method calls.
  ///
  /// If `lineTerminator` is `"\n"` then the written strings are not modified.
  //
  /// Setting `lineTerminator` to [Platform.lineTerminator] will result in
  /// "write" methods outputting the line endings for the platform:
  ///
  /// ```dart
  /// stdout.lineTerminator = Platform.lineTerminator;
  /// stderr.lineTerminator = Platform.lineTerminator;
  /// ```
  ///
  /// The value of `lineTerminator` has no effect on byte-oriented methods
  /// such as [add].
  ///
  /// The value of `lineTerminator` does not effect the output of the [print]
  /// function.
  ///
  /// Throws [ArgumentError] if set to a value other than `"\n"` or `"\r\n"`.
  String get lineTerminator => _windowsLineTerminator ? "\r\n" : "\n";
  set lineTerminator(String lineTerminator) {
    if (lineTerminator == "\r\n") {
      assert(!_lastWrittenCharIsCR || _windowsLineTerminator);
      _windowsLineTerminator = true;
    } else if (lineTerminator == "\n") {
      _windowsLineTerminator = false;
      _lastWrittenCharIsCR = false;
    } else {
      throw ArgumentError.value(
        lineTerminator,
        "lineTerminator",
        r'invalid line terminator, must be one of "\r" or "\r\n"',
      );
    }
  }

  Encoding get encoding => _sink.encoding;
  void set encoding(Encoding encoding) {
    _sink.encoding = encoding;
  }

  String _convertToWindowsLineTerminators(String string) {
    assert(!string.isEmpty);
    String result;
    if (_lastWrittenCharIsCR) {
      result = string.replaceAll(_newLineDetectorAfterCR, "\r\n");
    } else {
      result = string.replaceAll(_newLineDetector, "\r\n");
    }
    _lastWrittenCharIsCR = string.endsWith('\r');
    return result;
  }

  void _write(Object? object) {
    if (!_windowsLineTerminator) {
      _sink.write(object);
      return;
    }

    var string = object.toString();
    if (string.isEmpty) return;
    _sink.write(_convertToWindowsLineTerminators(string));
  }

  void write(Object? object) => _write(object);

  void writeln([Object? object = ""]) {
    if (!_windowsLineTerminator) {
      _sink.write('$object\n');
    } else {
      _sink.write(_convertToWindowsLineTerminators('$object\r\n'));
    }
  }

  void writeAll(Iterable objects, [String sep = ""]) {
    Iterator iterator = objects.iterator;
    if (!iterator.moveNext()) return;
    if (sep.isEmpty) {
      do {
        _write(iterator.current);
      } while (iterator.moveNext());
    } else {
      _write(iterator.current);
      while (iterator.moveNext()) {
        _write(sep);
        _write(iterator.current);
      }
    }
  }

  void add(List<int> data) {
    _lastWrittenCharIsCR = false;
    _sink.add(data);
  }

  void addError(error, [StackTrace? stackTrace]) {
    _sink.addError(error, stackTrace);
  }

  void writeCharCode(int charCode) {
    if (!_windowsLineTerminator) {
      _sink.writeCharCode(charCode);
      return;
    }

    _write(String.fromCharCode(charCode));
  }

  Future addStream(Stream<List<int>> stream) {
    _lastWrittenCharIsCR = false;
    return _sink.addStream(stream);
  }

  Future flush() => _sink.flush();
  Future close() => _sink.close();
  Future get done => _sink.done;
}

/// The type of object a standard IO stream can be attached to.
final class StdioType {
  static const StdioType terminal = const StdioType._("terminal");
  static const StdioType pipe = const StdioType._("pipe");
  static const StdioType file = const StdioType._("file");
  static const StdioType other = const StdioType._("other");

  final String name;
  const StdioType._(this.name);
  String toString() => "StdioType: $name";
}

final Stdin _stdin = _StdIOUtils._getStdioInputStream(_stdinFD);
final Stdout _stdout = _StdIOUtils._getStdioOutputStream(_stdoutFD);
final Stdout _stderr = _StdIOUtils._getStdioOutputStream(_stderrFD);

// These may be set to different values by the embedder by calling
// _setStdioFDs when initializing dart:io.
int _stdinFD = 0;
int _stdoutFD = 1;
int _stderrFD = 2;

@pragma('vm:entry-point', 'call')
void _setStdioFDs(int stdin, int stdout, int stderr) {
  _stdinFD = stdin;
  _stdoutFD = stdout;
  _stderrFD = stderr;
}

/// The standard input stream of data read by this program.
Stdin get stdin {
  return IOOverrides.current?.stdin ?? _stdin;
}

/// The standard output stream of data written by this program.
///
/// The `addError` API is inherited from  `StreamSink` and calling it will
/// result in an unhandled asynchronous error unless there is an error handler
/// on `done`.
Stdout get stdout {
  return IOOverrides.current?.stdout ?? _stdout;
}

/// The standard output stream of errors written by this program.
///
/// The `addError` API is inherited from  `StreamSink` and calling it will
/// result in an unhandled asynchronous error unless there is an error handler
/// on `done`.
Stdout get stderr {
  return IOOverrides.current?.stderr ?? _stderr;
}

/// Whether a stream is attached to a file, pipe, terminal, or
/// something else.
StdioType stdioType(object) {
  if (object is _StdStream) {
    object = object._stream;
  } else if (object == stdout || object == stderr) {
    int stdiofd = object == stdout ? _stdoutFD : _stderrFD;
    final type = _StdIOUtils._getStdioHandleType(stdiofd);
    if (type is OSError) {
      throw FileSystemException(
        "Failed to get type of stdio handle (fd $stdiofd)",
        "",
        type,
      );
    }
    switch (type) {
      case _stdioHandleTypeTerminal:
        return StdioType.terminal;
      case _stdioHandleTypePipe:
        return StdioType.pipe;
      case _stdioHandleTypeFile:
        return StdioType.file;
    }
  }
  if (object is _FileStream) {
    return StdioType.file;
  }
  if (object is Socket) {
    int? socketType = _StdIOUtils._socketType(object);
    if (socketType == null) return StdioType.other;
    switch (socketType) {
      case _stdioHandleTypeTerminal:
        return StdioType.terminal;
      case _stdioHandleTypePipe:
        return StdioType.pipe;
      case _stdioHandleTypeFile:
        return StdioType.file;
    }
  }
  if (object is _IOSinkImpl) {
    try {
      if (object._target is _FileStreamConsumer) {
        return StdioType.file;
      }
    } catch (e) {
      // Only the interface implemented, _sink not available.
    }
  }
  return StdioType.other;
}

class _StdIOUtils {
  external static _getStdioOutputStream(int fd);
  external static Stdin _getStdioInputStream(int fd);

  /// Returns the socket type or `null` if [socket] is not a builtin socket.
  external static int? _socketType(Socket socket);
  external static _getStdioHandleType(int fd);
}
