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

import 'package:file/file.dart';
import 'package:file/src/common.dart' as common;
import 'package:file/src/io.dart' as io;

import 'common.dart';
import 'node.dart';

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

/// 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 TypeChecker = void Function(Node node);

/// Throws a [io.FileSystemException] if [node] is not a directory.
void checkIsDir(Node node, PathGenerator path) {
  if (!isDirectory(node)) {
    throw common.notADirectory(path());
  }
}

/// Throws a [io.FileSystemException] if [expectedType] doesn't match
/// [actualType].
void checkType(
  FileSystemEntityType expectedType,
  FileSystemEntityType actualType,
  PathGenerator path,
) {
  if (expectedType != actualType) {
    switch (expectedType) {
      case FileSystemEntityType.directory:
        throw common.notADirectory(path());
      case FileSystemEntityType.file:
        assert(actualType == FileSystemEntityType.directory);
        throw common.isADirectory(path());
      case FileSystemEntityType.link:
        throw common.invalidArgument(path());
      default:
        // Should not happen
        throw AssertionError();
    }
  }
}

/// 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.writeOnly ||
    mode == io.FileMode.writeOnlyAppend;

/// 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 = Set<LinkNode>();

  Node node = link;
  while (isLink(node)) {
    link = node;
    if (!breadcrumbs.add(node)) {
      throw common.tooManyLevelsOfSymbolicLinks(path());
    }
    if (ledger != null) {
      if (link.fs.path.isAbsolute(link.target)) {
        ledger.clear();
      } else if (ledger.isNotEmpty) {
        ledger.removeLast();
      }
      ledger.addAll(link.target.split(link.fs.path.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;
}
