// Copyright (c) 2017, 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;

final _ioOverridesToken = new Object();

const _asyncRunZoned = runZoned;

/// Facilities for overriding various APIs of `dart:io` with mock
/// implementations.
///
/// This abstract base class should be extended with overrides for the
/// operations needed to construct mocks. The implementations in this base class
/// default to the actual `dart:io` implementation. For example:
///
/// ```dart
/// class MyDirectory implements Directory {
///   ...
///   // An implementation of the Directory interface
///   ...
/// }
///
/// void main() {
///   IOOverrides.runZoned(() {
///     ...
///     // Operations will use MyDirectory instead of dart:io's Directory
///     // implementation whenever Directory is used.
///     ...
///   }, createDirectory: (String path) => new MyDirectory(path));
/// }
/// ```
abstract class IOOverrides {
  static IOOverrides? _global;

  static IOOverrides? get current {
    return Zone.current[_ioOverridesToken] ?? _global;
  }

  /// The [IOOverrides] to use in the root [Zone].
  ///
  /// These are the [IOOverrides] that will be used in the root [Zone], and in
  /// [Zone]'s that do not set [IOOverrides] and whose ancestors up to the root
  /// [Zone] also do not set [IOOverrides].
  static set global(IOOverrides? overrides) {
    _global = overrides;
  }

  /// Runs [body] in a fresh [Zone] using the provided overrides.
  ///
  /// See the documentation on the corresponding methods of [IOOverrides] for
  /// information about what the optional arguments do.
  static R runZoned<R>(R body(),
      {
      // Directory
      Directory Function(String)? createDirectory,
      Directory Function()? getCurrentDirectory,
      void Function(String)? setCurrentDirectory,
      Directory Function()? getSystemTempDirectory,

      // File
      File Function(String)? createFile,

      // FileStat
      Future<FileStat> Function(String)? stat,
      FileStat Function(String)? statSync,

      // FileSystemEntity
      Future<bool> Function(String, String)? fseIdentical,
      bool Function(String, String)? fseIdenticalSync,
      Future<FileSystemEntityType> Function(String, bool)? fseGetType,
      FileSystemEntityType Function(String, bool)? fseGetTypeSync,

      // _FileSystemWatcher
      Stream<FileSystemEvent> Function(String, int, bool)? fsWatch,
      bool Function()? fsWatchIsSupported,

      // Link
      Link Function(String)? createLink,

      // Socket
      Future<Socket> Function(dynamic, int,
              {dynamic sourceAddress, Duration? timeout})?
          socketConnect,
      Future<ConnectionTask<Socket>> Function(dynamic, int,
              {dynamic sourceAddress})?
          socketStartConnect,

      // ServerSocket
      Future<ServerSocket> Function(dynamic, int,
              {int backlog, bool v6Only, bool shared})?
          serverSocketBind,

      // Standard Streams
      Stdin Function()? stdin,
      Stdout Function()? stdout,
      Stdout Function()? stderr}) {
    IOOverrides overrides = new _IOOverridesScope(
      // Directory
      createDirectory,
      getCurrentDirectory,
      setCurrentDirectory,
      getSystemTempDirectory,

      // File
      createFile,

      // FileStat
      stat,
      statSync,

      // FileSystemEntity
      fseIdentical,
      fseIdenticalSync,
      fseGetType,
      fseGetTypeSync,

      // _FileSystemWatcher
      fsWatch,
      fsWatchIsSupported,

      // Link
      createLink,

      // Socket
      socketConnect,
      socketStartConnect,

      // ServerSocket
      serverSocketBind,

      // Standard streams
      stdin,
      stdout,
      stderr,
    );
    return _asyncRunZoned<R>(body, zoneValues: {_ioOverridesToken: overrides});
  }

  /// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
  ///
  /// Note that [overrides] should be an instance of a class that extends
  /// [IOOverrides].
  static R runWithIOOverrides<R>(R body(), IOOverrides overrides) {
    return _asyncRunZoned<R>(body, zoneValues: {_ioOverridesToken: overrides});
  }

  // Directory

  /// Creates a new [Directory] object for the given [path].
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `new Directory()` and `new Directory.fromUri()`.
  Directory createDirectory(String path) => new _Directory(path);

  /// Returns the current working directory.
  ///
  /// When this override is installed, this function overrides the behavior of
  /// the static getter `Directory.current`
  Directory getCurrentDirectory() => _Directory.current;

  /// Sets the current working directory to be [path].
  ///
  /// When this override is installed, this function overrides the behavior of
  /// the setter `Directory.current`.
  void setCurrentDirectory(String path) {
    _Directory.current = path;
  }

  /// Returns the system temporary directory.
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `Directory.systemTemp`.
  Directory getSystemTempDirectory() => _Directory.systemTemp;

  // File

  /// Creates a new [File] object for the given [path].
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `new File()` and `new File.fromUri()`.
  File createFile(String path) => new _File(path);

  // FileStat

  /// Asynchronously returns [FileStat] information for [path].
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `FileStat.stat()`.
  Future<FileStat> stat(String path) {
    return FileStat._stat(path);
  }

  /// Returns [FileStat] information for [path].
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `FileStat.statSync()`.
  FileStat statSync(String path) {
    return FileStat._statSyncInternal(path);
  }

  // FileSystemEntity

  /// Asynchronously returns `true` if [path1] and [path2] are paths to the
  /// same file system object.
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `FileSystemEntity.identical`.
  Future<bool> fseIdentical(String path1, String path2) {
    return FileSystemEntity._identical(path1, path2);
  }

  /// Returns `true` if [path1] and [path2] are paths to the
  /// same file system object.
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `FileSystemEntity.identicalSync`.
  bool fseIdenticalSync(String path1, String path2) {
    return FileSystemEntity._identicalSync(path1, path2);
  }

  /// Asynchronously returns the [FileSystemEntityType] for [path].
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `FileSystemEntity.type`.
  Future<FileSystemEntityType> fseGetType(String path, bool followLinks) {
    return FileSystemEntity._getTypeRequest(
        utf8.encoder.convert(path), followLinks);
  }

  /// Returns the [FileSystemEntityType] for [path].
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `FileSystemEntity.typeSync`.
  FileSystemEntityType fseGetTypeSync(String path, bool followLinks) {
    return FileSystemEntity._getTypeSyncHelper(
        utf8.encoder.convert(path), followLinks);
  }

  // _FileSystemWatcher

  /// Returns a [Stream] of [FileSystemEvent]s.
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `FileSystemEntity.watch()`.
  Stream<FileSystemEvent> fsWatch(String path, int events, bool recursive) {
    return _FileSystemWatcher._watch(path, events, recursive);
  }

  /// Returns `true` when [FileSystemEntity.watch] is supported.
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `FileSystemEntity.isWatchSupported`.
  bool fsWatchIsSupported() => _FileSystemWatcher.isSupported;

  // Link

  /// Returns a new [Link] object for the given [path].
  ///
  /// When this override is installed, this function overrides the behavior of
  /// `new Link()` and `new Link.fromUri()`.
  Link createLink(String path) => new _Link(path);

  // Socket

  /// Asynchronously returns a [Socket] connected to the given host and port.
  ///
  /// When this override is installed, this functions overrides the behavior of
  /// `Socket.connect(...)`.
  Future<Socket> socketConnect(host, int port,
      {sourceAddress, Duration? timeout}) {
    return Socket._connect(host, port,
        sourceAddress: sourceAddress, timeout: timeout);
  }

  /// Asynchronously returns a [ConnectionTask] that connects to the given host
  /// and port when successful.
  ///
  /// When this override is installed, this functions overrides the behavior of
  /// `Socket.startConnect(...)`.
  Future<ConnectionTask<Socket>> socketStartConnect(host, int port,
      {sourceAddress}) {
    return Socket._startConnect(host, port, sourceAddress: sourceAddress);
  }

  // ServerSocket

  /// Asynchronously returns a [ServerSocket] that connects to the given address
  /// and port when successful.
  ///
  /// When this override is installed, this functions overrides the behavior of
  /// `ServerSocket.bind(...)`.
  Future<ServerSocket> serverSocketBind(address, int port,
      {int backlog = 0, bool v6Only = false, bool shared = false}) {
    return ServerSocket._bind(address, port,
        backlog: backlog, v6Only: v6Only, shared: shared);
  }

  // Standard streams

  /// The standard input stream of data read by this program.
  ///
  /// When this override is installed, this getter overrides the behavior of
  /// the top-level `stdin` getter.
  Stdin get stdin {
    return _stdin;
  }

  /// The standard output stream of data written by this program.
  ///
  /// When this override is installed, this getter overrides the behavior of
  /// the top-level `stdout` getter.
  Stdout get stdout {
    return _stdout;
  }

  /// The standard output stream of errors written by this program.
  ///
  /// When this override is installed, this getter overrides the behavior of
  /// the top-level `stderr` getter.
  Stdout get stderr {
    return _stderr;
  }
}

class _IOOverridesScope extends IOOverrides {
  final IOOverrides? _previous = IOOverrides.current;

  // Directory
  Directory Function(String)? _createDirectory;
  Directory Function()? _getCurrentDirectory;
  void Function(String)? _setCurrentDirectory;
  Directory Function()? _getSystemTempDirectory;

  // File
  File Function(String)? _createFile;

  // FileStat
  Future<FileStat> Function(String)? _stat;
  FileStat Function(String)? _statSync;

  // FileSystemEntity
  Future<bool> Function(String, String)? _fseIdentical;
  bool Function(String, String)? _fseIdenticalSync;
  Future<FileSystemEntityType> Function(String, bool)? _fseGetType;
  FileSystemEntityType Function(String, bool)? _fseGetTypeSync;

  // _FileSystemWatcher
  Stream<FileSystemEvent> Function(String, int, bool)? _fsWatch;
  bool Function()? _fsWatchIsSupported;

  // Link
  Link Function(String)? _createLink;

  // Socket
  Future<Socket> Function(dynamic, int,
      {dynamic sourceAddress, Duration? timeout})? _socketConnect;
  Future<ConnectionTask<Socket>> Function(dynamic, int,
      {dynamic sourceAddress})? _socketStartConnect;

  // ServerSocket
  Future<ServerSocket> Function(dynamic, int,
      {int backlog, bool v6Only, bool shared})? _serverSocketBind;

  // Standard streams
  Stdin Function()? _stdin;
  Stdout Function()? _stdout;
  Stdout Function()? _stderr;

  _IOOverridesScope(
    // Directory
    this._createDirectory,
    this._getCurrentDirectory,
    this._setCurrentDirectory,
    this._getSystemTempDirectory,

    // File
    this._createFile,

    // FileStat
    this._stat,
    this._statSync,

    // FileSystemEntity
    this._fseIdentical,
    this._fseIdenticalSync,
    this._fseGetType,
    this._fseGetTypeSync,

    // _FileSystemWatcher
    this._fsWatch,
    this._fsWatchIsSupported,

    // Link
    this._createLink,

    // Socket
    this._socketConnect,
    this._socketStartConnect,

    // ServerSocket
    this._serverSocketBind,

    // Standard streams
    this._stdin,
    this._stdout,
    this._stderr,
  );

  // Directory
  @override
  Directory createDirectory(String path) {
    if (_createDirectory != null) return _createDirectory!(path);
    if (_previous != null) return _previous!.createDirectory(path);
    return super.createDirectory(path);
  }

  @override
  Directory getCurrentDirectory() {
    if (_getCurrentDirectory != null) return _getCurrentDirectory!();
    if (_previous != null) return _previous!.getCurrentDirectory();
    return super.getCurrentDirectory();
  }

  @override
  void setCurrentDirectory(String path) {
    if (_setCurrentDirectory != null)
      _setCurrentDirectory!(path);
    else if (_previous != null)
      _previous!.setCurrentDirectory(path);
    else
      super.setCurrentDirectory(path);
  }

  @override
  Directory getSystemTempDirectory() {
    if (_getSystemTempDirectory != null) return _getSystemTempDirectory!();
    if (_previous != null) return _previous!.getSystemTempDirectory();
    return super.getSystemTempDirectory();
  }

  // File
  @override
  File createFile(String path) {
    if (_createFile != null) return _createFile!(path);
    if (_previous != null) return _previous!.createFile(path);
    return super.createFile(path);
  }

  // FileStat
  @override
  Future<FileStat> stat(String path) {
    if (_stat != null) return _stat!(path);
    if (_previous != null) return _previous!.stat(path);
    return super.stat(path);
  }

  @override
  FileStat statSync(String path) {
    if (_stat != null) return _statSync!(path);
    if (_previous != null) return _previous!.statSync(path);
    return super.statSync(path);
  }

  // FileSystemEntity
  @override
  Future<bool> fseIdentical(String path1, String path2) {
    if (_fseIdentical != null) return _fseIdentical!(path1, path2);
    if (_previous != null) return _previous!.fseIdentical(path1, path2);
    return super.fseIdentical(path1, path2);
  }

  @override
  bool fseIdenticalSync(String path1, String path2) {
    if (_fseIdenticalSync != null) return _fseIdenticalSync!(path1, path2);
    if (_previous != null) return _previous!.fseIdenticalSync(path1, path2);
    return super.fseIdenticalSync(path1, path2);
  }

  @override
  Future<FileSystemEntityType> fseGetType(String path, bool followLinks) {
    if (_fseGetType != null) return _fseGetType!(path, followLinks);
    if (_previous != null) return _previous!.fseGetType(path, followLinks);
    return super.fseGetType(path, followLinks);
  }

  @override
  FileSystemEntityType fseGetTypeSync(String path, bool followLinks) {
    if (_fseGetTypeSync != null) return _fseGetTypeSync!(path, followLinks);
    if (_previous != null) return _previous!.fseGetTypeSync(path, followLinks);
    return super.fseGetTypeSync(path, followLinks);
  }

  // _FileSystemWatcher
  @override
  Stream<FileSystemEvent> fsWatch(String path, int events, bool recursive) {
    if (_fsWatch != null) return _fsWatch!(path, events, recursive);
    if (_previous != null) return _previous!.fsWatch(path, events, recursive);
    return super.fsWatch(path, events, recursive);
  }

  @override
  bool fsWatchIsSupported() {
    if (_fsWatchIsSupported != null) return _fsWatchIsSupported!();
    if (_previous != null) return _previous!.fsWatchIsSupported();
    return super.fsWatchIsSupported();
  }

  // Link
  @override
  Link createLink(String path) {
    if (_createLink != null) return _createLink!(path);
    if (_previous != null) return _previous!.createLink(path);
    return super.createLink(path);
  }

  // Socket
  @override
  Future<Socket> socketConnect(host, int port,
      {sourceAddress, Duration? timeout}) {
    if (_socketConnect != null) {
      return _socketConnect!(host, port,
          sourceAddress: sourceAddress, timeout: timeout);
    }
    if (_previous != null) {
      return _previous!.socketConnect(host, port,
          sourceAddress: sourceAddress, timeout: timeout);
    }
    return super.socketConnect(host, port,
        sourceAddress: sourceAddress, timeout: timeout);
  }

  @override
  Future<ConnectionTask<Socket>> socketStartConnect(host, int port,
      {sourceAddress}) {
    if (_socketStartConnect != null) {
      return _socketStartConnect!(host, port, sourceAddress: sourceAddress);
    }
    if (_previous != null) {
      return _previous!
          .socketStartConnect(host, port, sourceAddress: sourceAddress);
    }
    return super.socketStartConnect(host, port, sourceAddress: sourceAddress);
  }

  // ServerSocket

  @override
  Future<ServerSocket> serverSocketBind(address, int port,
      {int backlog = 0, bool v6Only = false, bool shared = false}) {
    if (_serverSocketBind != null) {
      return _serverSocketBind!(address, port,
          backlog: backlog, v6Only: v6Only, shared: shared);
    }
    if (_previous != null) {
      return _previous!.serverSocketBind(address, port,
          backlog: backlog, v6Only: v6Only, shared: shared);
    }
    return super.serverSocketBind(address, port,
        backlog: backlog, v6Only: v6Only, shared: shared);
  }

  // Standard streams

  @override
  Stdin get stdin {
    return _stdin?.call() ?? _previous?.stdin ?? super.stdin;
  }

  @override
  Stdout get stdout {
    return _stdout?.call() ?? _previous?.stdout ?? super.stdout;
  }

  @override
  Stdout get stderr {
    return _stderr?.call() ?? _previous?.stderr ?? super.stderr;
  }
}
