// 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.

part of dart.io;

/// A reference to a directory (or _folder_) on the file system.
///
/// A [Directory] is an object holding a [path] on which operations can
/// be performed. The path to the directory can be [absolute] or relative.
/// It allows access to the [parent] directory,
/// since it is a [FileSystemEntity].
///
/// The [Directory] also provides static access to the system's temporary
/// file directory, [systemTemp], and the ability to access and change
/// the [current] directory.
///
/// Create a new [Directory] to give access the directory with the specified
/// path:
/// ```dart
/// var myDir = Directory('myDir');
/// ```
/// Most instance methods of [Directory] exist in both synchronous
/// and asynchronous variants, for example, [create] and [createSync].
/// Unless you have a specific reason for using the synchronous version
/// of a method, prefer the asynchronous version to avoid blocking your program.
///
/// ## Create a directory
///
/// The following code sample creates a directory using the [create] method.
/// By setting the `recursive` parameter to true, you can create the
/// named directory and all its necessary parent directories,
/// if they do not already exist.
/// ```dart
/// import 'dart:io';
///
/// void main() async {
///   // Creates dir/ and dir/subdir/.
///   var directory = await Directory('dir/subdir').create(recursive: true);
///   print(directory.path);
/// }
/// ```
/// ## List the entries of a directory
///
/// Use the [list] or [listSync] methods to get the files and directories
/// contained in a directory.
/// Set `recursive` to true to recursively list all subdirectories.
/// Set `followLinks` to true to follow symbolic links.
/// The list method returns a [Stream] of [FileSystemEntity] objects.
/// Listen on the stream to access each object as it is found:
/// ```dart
/// import 'dart:io';
///
/// void main() async {
///   // Get the system temp directory.
///   var systemTempDir = Directory.systemTemp;
///
///   // List directory contents, recursing into sub-directories,
///   // but not following symbolic links.
///   await for (var entity in
///       systemTempDir.list(recursive: true, followLinks: false)) {
///     print(entity.path);
///   }
/// }
/// ```
/// ## The use of asynchronous methods
///
/// I/O operations can block a program for some period of time while it waits for
/// the operation to complete. To avoid this, all
/// methods involving I/O have an asynchronous variant which returns a [Future].
/// This future completes when the I/O operation finishes. While the I/O
/// operation is in progress, the Dart program is not blocked,
/// and can perform other operations.
///
/// For example,
/// the [exists] method, which determines whether the directory exists,
/// returns a boolean value asynchronously using a [Future].
/// ```dart
/// import 'dart:io';
///
/// void main() async {
///   final myDir = Directory('dir');
///   var isThere = await myDir.exists();
///   print(isThere ? 'exists' : 'nonexistent');
/// }
/// ```
///
/// In addition to [exists], the [stat], [rename],
/// and other methods are also asynchronous.
///
/// ## Other resources
///
/// * The [Files and directories](https://dart.dev/guides/libraries/library-tour#files-and-directories)
///   section of the library tour.
///
/// * [Write Command-Line Apps](https://dart.dev/tutorials/server/cmdline),
///   a tutorial about writing command-line apps, includes information about
///   files and directories.
@pragma("vm:entry-point")
abstract interface class Directory implements FileSystemEntity {
  /// Gets the path of this directory.
  String get path;

  /// Creates a [Directory] object.
  ///
  /// If [path] is a relative path, it will be interpreted relative to the
  /// current working directory (see [Directory.current]), when used.
  ///
  /// If [path] is an absolute path, it will be immune to changes to the
  /// current working directory.
  @pragma("vm:entry-point")
  factory Directory(String path) {
    final IOOverrides? overrides = IOOverrides.current;
    if (overrides == null) {
      return new _Directory(path);
    }
    return overrides.createDirectory(path);
  }

  @pragma("vm:entry-point")
  factory Directory.fromRawPath(Uint8List path) {
    // TODO(bkonyi): Handle overrides.
    return new _Directory.fromRawPath(path);
  }

  /// Create a [Directory] from a URI.
  ///
  /// If [uri] cannot reference a directory this throws [UnsupportedError].
  factory Directory.fromUri(Uri uri) => new Directory(uri.toFilePath());

  /// Creates a directory object pointing to the current working
  /// directory.
  static Directory get current {
    final IOOverrides? overrides = IOOverrides.current;
    if (overrides == null) {
      return _Directory.current;
    }
    return overrides.getCurrentDirectory();
  }

  /// A [Uri] representing the directory's location.
  ///
  /// The URI's scheme is always "file" if the entity's [path] is
  /// absolute, otherwise the scheme will be empty and the URI relative.
  /// The URI's path always ends in a slash ('/').
  Uri get uri;

  /// Sets the current working directory of the Dart process.
  ///
  /// This affects all running isolates.
  /// The new value set can be either a [Directory] or a [String].
  ///
  /// The new value is passed to the OS's system call unchanged, so a
  /// relative path passed as the new working directory will be
  /// resolved by the OS.
  ///
  /// Note that setting the current working directory is a synchronous
  /// operation and that it changes the working directory of *all*
  /// isolates.
  ///
  /// Use this with care — especially when working with asynchronous
  /// operations and multiple isolates. Changing the working directory,
  /// while asynchronous operations are pending or when other isolates
  /// are working with the file system, can lead to unexpected results.
  static void set current(dynamic path) {
    // Disallow implicit casts to avoid bugs like
    // <https://github.com/dart-lang/sdk/issues/52140>.
    //
    // This can be removed if `strict-casts` is enabled.
    path as Object?;

    final IOOverrides? overrides = IOOverrides.current;
    if (overrides == null) {
      _Directory.current = path;
      return;
    }

    // IOOverrides.setCurrentDirectory accepts only a [String].
    overrides.setCurrentDirectory(switch (path) {
      String s => s,
      Directory d => d.path,
      _ =>
        throw ArgumentError(
          '${Error.safeToString(path)} is not a String or'
          ' Directory',
        ),
    });
  }

  /// Creates the directory if it doesn't exist.
  ///
  /// If [recursive] is false, only the last directory in the path is
  /// created. If [recursive] is true, all non-existing path components
  /// are created. If the directory already exists nothing is done.
  ///
  /// Returns a `Future<Directory>` that completes with this
  /// directory once it has been created. If the directory cannot be
  /// created the future completes with an exception.
  Future<Directory> create({bool recursive = false});

  /// Synchronously creates the directory if it doesn't exist.
  ///
  /// If [recursive] is false, only the last directory in the path is
  /// created. If [recursive] is true, all non-existing path components
  /// are created. If the directory already exists nothing is done.
  ///
  /// If the directory cannot be created an exception is thrown.
  void createSync({bool recursive = false});

  /// The system temp directory.
  ///
  /// This is the directory provided by the operating system for creating
  /// temporary files and directories in.
  /// The location of the system temporary directory is platform-dependent,
  /// and may be controlled by an environment variable on some platforms.
  static Directory get systemTemp {
    final IOOverrides? overrides = IOOverrides.current;
    if (overrides == null) {
      return _Directory.systemTemp;
    }
    return overrides.getSystemTempDirectory();
  }

  /// Creates a temporary directory in this directory.
  ///
  /// Additional random characters are appended to [prefix]
  /// to produce a unique directory name.
  /// If [prefix] is missing or null, the empty string is used as [prefix].
  ///
  /// Returns a `Future<Directory>` that completes with the newly
  /// created temporary directory.
  Future<Directory> createTemp([String? prefix]);

  /// Synchronously creates a temporary directory in this directory.
  ///
  /// Additional random characters are appended to [prefix] to produce
  /// a unique directory name. If [prefix] is missing or null, the empty
  /// string is used as [prefix].
  ///
  /// Returns the newly created temporary directory.
  Directory createTempSync([String? prefix]);

  Future<String> resolveSymbolicLinks();

  String resolveSymbolicLinksSync();

  /// Renames this directory.
  ///
  /// Returns a `Future<Directory>` that completes
  /// with a [Directory] for the renamed directory.
  ///
  /// If [newPath] identifies an existing directory, then the behavior is
  /// platform-specific. On all platforms, the future completes with a
  /// [FileSystemException] if the existing directory is not empty. On POSIX
  /// systems, if [newPath] identifies an existing empty directory then that
  /// directory is deleted before this directory is renamed.
  ///
  /// If [newPath] identifies an existing file or link, the operation
  /// fails and the future completes with a [FileSystemException].
  Future<Directory> rename(String newPath);

  /// Synchronously renames this directory.
  ///
  /// Returns a [Directory] for the renamed directory.
  ///
  /// If [newPath] identifies an existing directory, then the behavior is
  /// platform-specific. On all platforms, a [FileSystemException] is thrown
  /// if the existing directory is not empty. On POSIX systems, if [newPath]
  /// identifies an existing empty directory then that directory is deleted
  /// before this directory is renamed.
  ///
  /// If [newPath] identifies an existing file or link the operation
  /// fails and a [FileSystemException] is thrown.
  Directory renameSync(String newPath);

  /// Deletes this [Directory].
  ///
  /// If [recursive] is `false`:
  ///
  ///  * If [path] corresponds to an empty directory, then that directory is
  ///    deleted. If [path] corresponds to a link, and that link resolves
  ///    to a directory, then the link at [path] will be deleted. In all
  ///    other cases, [delete] completes with a [FileSystemException].
  ///
  /// If [recursive] is `true`:
  ///
  ///  * The [FileSystemEntity] at [path] is deleted regardless of type. If
  ///    [path] corresponds to a file or link, then that file or link is
  ///    deleted. If [path] corresponds to a directory, then it and all
  ///    sub-directories and files in those directories are deleted. Links
  ///    are not followed when deleting recursively. Only the link is deleted,
  ///    not its target. This behavior allows [delete] to be used to
  ///    unconditionally delete any file system object.
  ///
  /// If this [Directory] cannot be deleted, then [delete] completes with a
  /// [FileSystemException].
  Future<FileSystemEntity> delete({bool recursive = false});

  /// Synchronously deletes this [Directory].
  ///
  /// If [recursive] is `false`:
  ///
  ///  * If [path] corresponds to an empty directory, then that directory is
  ///    deleted. If [path] corresponds to a link, and that link resolves
  ///    to a directory, then the link at [path] will be deleted. In all
  ///    other cases, [delete] throws a [FileSystemException].
  ///
  /// If [recursive] is `true`:
  ///
  ///  * The [FileSystemEntity] at [path] is deleted regardless of type. If
  ///    [path] corresponds to a file or link, then that file or link is
  ///    deleted. If [path] corresponds to a directory, then it and all
  ///    sub-directories and files in those directories are deleted. Links
  ///    are not followed when deleting recursively. Only the link is deleted,
  ///    not its target. This behavior allows [delete] to be used to
  ///    unconditionally delete any file system object.
  ///
  /// If this [Directory] cannot be deleted, then [delete] throws a
  /// [FileSystemException].
  void deleteSync({bool recursive = false});

  /// A [Directory] whose path is the absolute path of this [Directory].
  ///
  /// The absolute path is computed by prefixing
  /// a relative path with the current working directory,
  /// or by returning an absolute path unchanged.
  Directory get absolute;

  /// Lists the sub-directories and files of this [Directory].
  ///
  /// Optionally recurses into sub-directories.
  ///
  /// If [followLinks] is `false`, then any symbolic links found
  /// are reported as [Link] objects, rather than as directories or files,
  /// and are not recursed into.
  ///
  /// If [followLinks] is `true`, then working links are reported as
  /// directories or files, depending on what they point to,
  /// and links to directories are recursed into if [recursive] is `true`.
  ///
  /// Broken links are reported as [Link] objects.
  ///
  /// If a symbolic link makes a loop in the file system, then a recursive
  /// listing will not follow a link twice in the
  /// same recursive descent, but will report it as a [Link]
  /// the second time it is seen.
  ///
  /// The result is a [Stream] of [FileSystemEntity] objects for the
  /// directories, files, and links. The [Stream] will be in an arbitrary
  /// order and does not include the special entries `'.'` and `'..'`.
  Stream<FileSystemEntity> list({
    bool recursive = false,
    bool followLinks = true,
  });

  /// Lists the sub-directories and files of this [Directory].
  /// Optionally recurses into sub-directories.
  ///
  /// If [followLinks] is `false`, then any symbolic links found
  /// are reported as [Link] objects, rather than as directories or files,
  /// and are not recursed into.
  ///
  /// If [followLinks] is `true`, then working links are reported as
  /// directories or files, depending on what they point to,
  /// and links to directories are recursed into if [recursive] is `true`.
  ///
  /// Broken links are reported as [Link] objects.
  ///
  /// If a link makes a loop in the file system, then a recursive
  /// listing will not follow a link twice in the
  /// same recursive descent, but will report it as a [Link]
  /// the second time it is seen.
  ///
  /// Returns a [List] containing [FileSystemEntity] objects for the
  /// directories, files, and links. The [List] will be in an arbitrary order
  /// and does not include the special entries `'.'` and `'..'`.
  List<FileSystemEntity> listSync({
    bool recursive = false,
    bool followLinks = true,
  });

  /// Returns a human readable representation of this [Directory].
  String toString();
}
