// 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 file.src.backends.memory;

/// Checks if `node.type` returns [io.FileSystemEntityType.FILE].
bool _isFile(_Node node) => node?.type == io.FileSystemEntityType.FILE;

/// Checks if `node.type` returns [io.FileSystemEntityType.DIRECTORY].
bool _isDirectory(_Node node) =>
    node?.type == io.FileSystemEntityType.DIRECTORY;

/// Checks if `node.type` returns [io.FileSystemEntityType.LINK].
bool _isLink(_Node node) => node?.type == io.FileSystemEntityType.LINK;

/// Tells whether the specified path represents an absolute path.
bool _isAbsolute(String path) => path.startsWith(_separator);

/// Generates a path to use in error messages.
typedef dynamic _PathGenerator();

/// Validator function that is expected to throw a [FileSystemException] if
/// the node does not represent the type that is expected in any given context.
typedef void _TypeChecker(_Node node);

/// Throws a [io.FileSystemException] if [node] is null.
void _checkExists(_Node node, _PathGenerator path) {
  if (node == null) {
    throw new io.FileSystemException('No such file or directory', path());
  }
}

/// Throws a [io.FileSystemException] if [node] is not a directory.
void _checkIsDir(_Node node, _PathGenerator path) {
  if (!_isDirectory(node)) {
    throw new io.FileSystemException('Not a directory', path());
  }
}

/// Throws a [io.FileSystemException] if [expectedType] doesn't match
/// [actualType].
void _checkType(
  FileSystemEntityType expectedType,
  FileSystemEntityType actualType,
  _PathGenerator path,
) {
  if (expectedType != actualType) {
    String msg;
    switch (expectedType) {
      case FileSystemEntityType.DIRECTORY:
        msg = 'Not a directory';
        break;
      case FileSystemEntityType.FILE:
        assert(actualType == FileSystemEntityType.DIRECTORY);
        msg = 'Is a directory';
        break;
      case FileSystemEntityType.LINK:
        msg = 'Invalid argument';
        break;
      default:
        // Should not happen
        throw new AssertionError();
    }
    throw new io.FileSystemException(msg, path());
  }
}

/// Tells if the specified file mode represents a write mode.
bool _isWriteMode(io.FileMode mode) =>
    mode == io.FileMode.WRITE ||
    mode == io.FileMode.APPEND ||
    mode == io.FileMode.WRITE_ONLY ||
    mode == io.FileMode.WRITE_ONLY_APPEND;

/// Returns a [_PathGenerator] that generates a subpath of the constituent
/// [parts] (from [start]..[end], inclusive).
_PathGenerator _subpath(List<String> parts, int start, int end) {
  return () => parts.sublist(start, end + 1).join(_separator);
}

/// Tells whether the given string is empty.
bool _isEmpty(String str) => str.isEmpty;

/// Returns the node ultimately referred to by [link]. This will resolve
/// the link references (following chains of links as necessary) and return
/// the node at the end of the link chain.
///
/// If a loop in the link chain is found, this will throw a
/// [FileSystemException], calling [path] to generate the path.
///
/// If [ledger] is specified, the resolved path to the terminal node will be
/// appended to the ledger (or overwritten in the ledger if a link target
/// specified an absolute path). The path will not be normalized, meaning
/// `..` and `.` path segments may be present.
///
/// If [tailVisitor] is specified, it will be invoked for the tail element of
/// the last link in the symbolic link chain, and its return value will be the
/// return value of this method (thus allowing callers to create the entity
/// at the end of the chain on demand).
_Node _resolveLinks(
  _LinkNode link,
  _PathGenerator path, {
  List<String> ledger,
  _Node tailVisitor(_DirectoryNode parent, String childName, _Node child),
}) {
  // Record a breadcrumb trail to guard against symlink loops.
  Set<_LinkNode> breadcrumbs = new Set<_LinkNode>();

  _Node node = link;
  while (_isLink(node)) {
    link = node;
    if (!breadcrumbs.add(node)) {
      throw new io.FileSystemException(
          'Too many levels of symbolic links', path());
    }
    if (ledger != null) {
      if (_isAbsolute(link.target)) {
        ledger.clear();
      } else if (ledger.isNotEmpty) {
        ledger.removeLast();
      }
      ledger.addAll(link.target.split(_separator));
    }
    node = link.getReferent(
      tailVisitor: (_DirectoryNode parent, String childName, _Node child) {
        if (tailVisitor != null && !_isLink(child)) {
          // Only invoke [tailListener] on the final resolution pass.
          child = tailVisitor(parent, childName, child);
        }
        return child;
      },
    );
  }

  return node;
}
