// 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";

/// References to filesystem links.
@pragma("vm:entry-point")
abstract interface class Link implements FileSystemEntity {
  /// Creates a Link object.
  @pragma("vm:entry-point")
  factory Link(String path) {
    final IOOverrides? overrides = IOOverrides.current;
    if (overrides == null) {
      return new _Link(path);
    }
    return overrides.createLink(path);
  }

  @pragma("vm:entry-point")
  factory Link.fromRawPath(Uint8List rawPath) {
    // TODO(bkonyi): handle overrides
    return new _Link.fromRawPath(rawPath);
  }

  /// Creates a [Link] 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.
  factory Link.fromUri(Uri uri) => new Link(uri.toFilePath());

  /// Creates a symbolic link in the file system.
  ///
  /// The created link will point to the path at [target], whether that path
  /// exists or not.
  ///
  /// Returns a `Future<Link>` that completes with
  /// the link when it has been created. If the link path already exists,
  /// the future will complete with an error.
  ///
  /// If [recursive] is `false`, the default, the link is created
  /// only if all directories in its path exist.
  /// If [recursive] is `true`, all non-existing parent paths
  /// are created first. The directories in the path of [target] are
  /// not affected, unless they are also in [path].
  ///
  /// On the Windows platform, this call will create a true symbolic link
  /// instead of a junction. Windows treats links to files and links to
  /// directories as different and non-interchangable kinds of links.
  /// Each link is either a file-link or a directory-link, and the type is
  /// chosen when the link is created, and the link then counts as either a
  /// file or directory for most purposes. Different Win32 API calls are
  /// used to manipulate each. For example, the `DeleteFile` function is
  /// used to delete links to files, and `RemoveDirectory` must be used to
  /// delete links to directories.
  ///
  /// The created Windows symbolic link will match the type of the [target],
  /// if [target] exists, otherwise a file-link is created. The type of the
  /// created link will not change if [target] is later replaced by something
  /// of a different type, but then the link will not be resolvable by
  /// [resolveSymbolicLinks].
  ///
  /// In order to create a symbolic link on Windows, Dart must be run in
  /// Administrator mode or the system must have Developer Mode enabled,
  /// otherwise a [FileSystemException] will be raised with
  /// `ERROR_PRIVILEGE_NOT_HELD` set as the errno when this call is made.
  ///
  /// On other platforms, the POSIX `symlink()` call is used to make a symbolic
  /// link containing the string [target]. If [target] is a relative path,
  /// it will be interpreted relative to the directory containing the link.
  Future<Link> create(String target, {bool recursive = false});

  /// Creates a symbolic link in the file system.
  ///
  /// The created link will point to the path at [target], whether that path
  /// exists or not.
  ///
  /// If the link path already exists, an exception will be thrown.
  ///
  /// If [recursive] is `false`, the default, the link is created only if all
  /// directories in its path exist. If [recursive] is `true`, all
  /// non-existing parent paths are created first. The directories in
  /// the path of [target] are not affected, unless they are also in [path].
  ///
  /// On the Windows platform, this call will create a true symbolic link
  /// instead of a junction. Windows treats links to files and links to
  /// directories as different and non-interchangable kinds of links.
  /// Each link is either a file-link or a directory-link, and the type is
  /// chosen when the link is created, and the link then counts as either a
  /// file or directory for most purposes. Different Win32 API calls are
  /// used to manipulate each.  For example, the `DeleteFile` function is
  /// used to delete links to files, and `RemoveDirectory` must be used to
  /// delete links to directories.
  ///
  /// The created Windows symbolic link will match the type of the [target],
  /// if [target] exists, otherwise a file-link is created. The type of the
  /// created link will not change if [target] is later replaced by something
  /// of a different type, but then the link will not be resolvable by
  /// [resolveSymbolicLinks].
  ///
  /// In order to create a symbolic link on Windows, Dart must be run in
  /// Administrator mode or the system must have Developer Mode enabled,
  /// otherwise a [FileSystemException] will be raised with
  /// `ERROR_PRIVILEGE_NOT_HELD` set as the errno when this call is made.
  ///
  /// On other platforms, the POSIX `symlink()` call is used to make a symbolic
  /// link containing the string [target]. If [target] is a relative path,
  /// it will be interpreted relative to the directory containing the link.
  void createSync(String target, {bool recursive = false});

  /// Synchronously updates an existing link.
  ///
  /// Deletes the existing link at [path] and uses [createSync] to create a new
  /// link to [target]. Throws [PathNotFoundException] if the original link
  /// does not exist or any [FileSystemException] that [deleteSync] or
  /// [createSync] can throw.
  void updateSync(String target);

  /// Updates an existing link.
  ///
  /// Deletes the existing link at [path] and creates a new link to [target],
  /// using [create].
  ///
  /// Returns a future which completes with this `Link` if successful,
  /// and with a [PathNotFoundException] if there is no existing link at [path],
  /// or with any [FileSystemException] that [delete] or [create] can throw.
  Future<Link> update(String target);

  Future<String> resolveSymbolicLinks();

  String resolveSymbolicLinksSync();

  /// Renames this link.
  ///
  /// Returns a `Future<Link>` that completes with a [Link]
  /// for the renamed link.
  ///
  /// If [newPath] identifies an existing file or link, that entity is removed
  /// first. If [newPath] identifies an existing directory then the future
  /// completes with a [FileSystemException].
  Future<Link> rename(String newPath);

  /// Synchronously renames this link.
  ///
  /// Returns a [Link] instance for the renamed link.
  ///
  /// If [newPath] identifies an existing file or link, that entity is removed
  /// first. If [newPath] identifies an existing directory then
  /// [FileSystemException] is thrown.
  Link renameSync(String newPath);

  /// Deletes this [Link].
  ///
  /// If [recursive] is `false`:
  ///
  ///  * If [path] corresponds to a link then that path is deleted. Otherwise,
  ///    [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 [Link] cannot be deleted, then [delete] completes with a
  /// [FileSystemException].
  Future<FileSystemEntity> delete({bool recursive = false});

  /// Synchronously deletes this [Link].
  ///
  /// If [recursive] is `false`:
  ///
  ///  * If [path] corresponds to a link then that path is deleted. Otherwise,
  ///    [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 [Link] cannot be deleted, then [delete] throws a
  /// [FileSystemException].
  void deleteSync({bool recursive = false});

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

  /// Gets the target of the link.
  ///
  /// Returns a future that completes with the path to the target.
  ///
  /// If the returned target is a relative path, it is relative to the
  /// directory containing the link.
  ///
  /// If the link does not exist, or is not a link, the future completes with
  /// a [FileSystemException].
  Future<String> target();

  /// Synchronously gets the target of the link.
  ///
  /// Returns the path to the target.
  ///
  /// If the returned target is a relative path, it is relative to the
  /// directory containing the link.
  ///
  /// If the link does not exist, or is not a link,
  /// throws a [FileSystemException].
  String targetSync();
}

class _Link extends FileSystemEntity implements Link {
  final String _path;
  final Uint8List _rawPath;

  _Link(String path)
    : _path = path,
      _rawPath = FileSystemEntity._toUtf8Array(path);

  _Link.fromRawPath(Uint8List rawPath)
    : _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath),
      _path = FileSystemEntity._toStringFromUtf8Array(rawPath);

  String get path => _path;

  String toString() => "Link: '$path'";

  Future<bool> exists() => FileSystemEntity._isLinkRaw(_rawPath);

  bool existsSync() => FileSystemEntity._isLinkRawSync(_rawPath);

  Link get absolute => isAbsolute ? this : _Link(_absolutePath);

  Future<Link> create(String target, {bool recursive = false}) {
    var result = recursive
        ? parent.create(recursive: true)
        : new Future.value(null);
    return result
        .then(
          (_) => _File._dispatchWithNamespace(_IOService.fileCreateLink, [
            null,
            _rawPath,
            target,
          ]),
        )
        .then((response) {
          _checkForErrorResponse(
            response,
            "Cannot create link to target '$target'",
            path,
          );
          return this;
        });
  }

  void createSync(String target, {bool recursive = false}) {
    if (recursive) {
      parent.createSync(recursive: true);
    }
    var result = _File._createLink(_Namespace._namespace, _rawPath, target);
    throwIfError(result, "Cannot create link", path);
  }

  void updateSync(String target) {
    // TODO(12414): Replace with atomic update, where supported by platform.
    // Atomically changing a link can be done by creating the new link, with
    // a different name, and using the rename() posix call to move it to
    // the old name atomically.
    deleteSync();
    createSync(target);
  }

  Future<Link> update(String target) {
    // TODO(12414): Replace with atomic update, where supported by platform.
    // Atomically changing a link can be done by creating the new link, with
    // a different name, and using the rename() posix call to move it to
    // the old name atomically.
    return delete().then<Link>((_) => create(target));
  }

  Future<Link> _delete({bool recursive = false}) {
    if (recursive) {
      return new Directory.fromRawPath(
        _rawPath,
      ).delete(recursive: true).then((_) => this);
    }
    return _File._dispatchWithNamespace(_IOService.fileDeleteLink, [
      null,
      _rawPath,
    ]).then((response) {
      _checkForErrorResponse(response, "Cannot delete link", path);
      return this;
    });
  }

  void _deleteSync({bool recursive = false}) {
    if (recursive) {
      return new Directory.fromRawPath(_rawPath).deleteSync(recursive: true);
    }
    var result = _File._deleteLinkNative(_Namespace._namespace, _rawPath);
    throwIfError(result, "Cannot delete link", path);
  }

  Future<Link> rename(String newPath) {
    return _File._dispatchWithNamespace(_IOService.fileRenameLink, [
      null,
      _rawPath,
      newPath,
    ]).then((response) {
      _checkForErrorResponse(
        response,
        "Cannot rename link to '$newPath'",
        path,
      );
      return new Link(newPath);
    });
  }

  Link renameSync(String newPath) {
    var result = _File._renameLink(_Namespace._namespace, _rawPath, newPath);
    throwIfError(result, "Cannot rename link '$path' to '$newPath'");
    return new Link(newPath);
  }

  Future<String> target() {
    return _File._dispatchWithNamespace(_IOService.fileLinkTarget, [
      null,
      _rawPath,
    ]).then((response) {
      _checkForErrorResponse(response, "Cannot get target of link", path);
      return response as String;
    });
  }

  String targetSync() {
    var result = _File._linkTarget(_Namespace._namespace, _rawPath);
    throwIfError(result, "Cannot read link", path);
    return result;
  }

  static throwIfError(Object? result, String msg, [String path = ""]) {
    if (result is OSError) {
      throw FileSystemException._fromOSError(result, msg, path);
    }
  }
}
