// 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 _Directory(path);
    }
    return overrides.createDirectory(path);
  }

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

  /// Create a [Directory] from a URI.
  ///
  /// If [uri] cannot reference a directory this throws [UnsupportedError].
  factory Directory.fromUri(Uri uri) => 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();
}
