// 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 'dart:async';

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

import 'common.dart';
import 'memory_directory.dart';
import 'node.dart';
import 'style.dart';
import 'utils.dart' as utils;

/// Validator function for use with `_renameSync`. This will be invoked if the
/// rename would overwrite an existing entity at the new path. If this operation
/// should not be allowed, this function is expected to throw a
/// [io.FileSystemException]. The lack of such an exception will be interpreted
/// as the overwrite being permissible.
typedef RenameOverwriteValidator<T extends Node> = void Function(
    T existingNode);

/// Base class for all in-memory file system entity types.
abstract class MemoryFileSystemEntity implements FileSystemEntity {
  /// Constructor for subclasses.
  const MemoryFileSystemEntity(this.fileSystem, this.path);

  @override
  final NodeBasedFileSystem fileSystem;

  @override
  final String path;

  @override
  String get dirname => fileSystem.path.dirname(path);

  @override
  String get basename => fileSystem.path.basename(path);

  /// Returns the expected type of this entity, which may differ from the type
  /// of the node that's found at the path specified by this entity.
  io.FileSystemEntityType get expectedType;

  /// Gets the node that backs this file system entity, or null if this
  /// entity does not exist.
  @protected
  Node? get backingOrNull {
    try {
      return fileSystem.findNode(path);
    } on io.FileSystemException {
      return null;
    }
  }

  /// Gets the node that backs this file system entity. Throws a
  /// [io.FileSystemException] if this entity doesn't exist.
  ///
  /// The type of the node is not guaranteed to match [expectedType].
  @protected
  Node get backing {
    Node? node = fileSystem.findNode(path);
    checkExists(node, () => path);
    return node!;
  }

  /// Gets the node that backs this file system entity, or if that node is
  /// a symbolic link, the target node. This also will check that the type of
  /// the node (after symlink resolution) matches [expectedType]. If the type
  /// doesn't match, this will throw a [io.FileSystemException].
  @protected
  Node get resolvedBacking {
    Node node = backing;
    node = utils.isLink(node)
        ? utils.resolveLinks(node as LinkNode, () => path)
        : node;
    utils.checkType(expectedType, node.type, () => path);
    return node;
  }

  /// Checks the expected type of this file system entity against the specified
  /// node's `stat` type, throwing a [FileSystemException] if the types don't
  /// match. Note that since this checks the node's `stat` type, symbolic links
  /// will be resolved to their target type for the purpose of this validation.
  ///
  /// Protected methods that accept a `checkType` argument will default to this
  /// method if the `checkType` argument is unspecified.
  @protected
  void defaultCheckType(Node node) {
    utils.checkType(expectedType, node.stat.type, () => path);
  }

  @override
  Uri get uri {
    return Uri.file(path, windows: fileSystem.style == FileSystemStyle.windows);
  }

  @override
  Future<bool> exists() async => existsSync();

  @override
  Future<String> resolveSymbolicLinks() async => resolveSymbolicLinksSync();

  @override
  String resolveSymbolicLinksSync() {
    if (path.isEmpty) {
      throw common.noSuchFileOrDirectory(path);
    }
    List<String> ledger = <String>[];
    if (isAbsolute) {
      ledger.add(fileSystem.style.drive);
    }
    Node? node = fileSystem.findNode(path,
        pathWithSymlinks: ledger, followTailLink: true);
    checkExists(node, () => path);
    String resolved = ledger.join(fileSystem.path.separator);
    if (resolved == fileSystem.style.drive) {
      resolved = fileSystem.style.root;
    } else if (!fileSystem.path.isAbsolute(resolved)) {
      resolved = fileSystem.cwd + fileSystem.path.separator + resolved;
    }
    return fileSystem.path.normalize(resolved);
  }

  @override
  Future<io.FileStat> stat() => fileSystem.stat(path);

  @override
  io.FileStat statSync() => fileSystem.statSync(path);

  @override
  Future<FileSystemEntity> delete({bool recursive = false}) async {
    deleteSync(recursive: recursive);
    return this;
  }

  @override
  void deleteSync({bool recursive = false}) =>
      internalDeleteSync(recursive: recursive);

  @override
  Stream<io.FileSystemEvent> watch({
    int events = io.FileSystemEvent.all,
    bool recursive = false,
  }) =>
      throw UnsupportedError('Watching not supported in MemoryFileSystem');

  @override
  bool get isAbsolute => fileSystem.path.isAbsolute(path);

  @override
  FileSystemEntity get absolute {
    String absolutePath = path;
    if (!fileSystem.path.isAbsolute(absolutePath)) {
      absolutePath = fileSystem.path.join(fileSystem.cwd, absolutePath);
    }
    return clone(absolutePath);
  }

  @override
  Directory get parent => MemoryDirectory(fileSystem, dirname);

  /// Helper method for subclasses wishing to synchronously create this entity.
  /// This method will traverse the path to this entity one segment at a time,
  /// calling [createChild] for each segment whose child does not already exist.
  ///
  /// When [createChild] is invoked:
  /// - `parent` will be the parent node for the current segment and is
  ///   guaranteed to be non-null.
  /// - `isFinalSegment` will indicate whether the current segment is the tail
  ///   segment, which in turn indicates that this is the segment into which to
  ///   create the node for this entity.
  ///
  /// This method returns with the backing node for the entity at this [path].
  /// If an entity already existed at this path, [createChild] will not be
  /// invoked at all, and this method will return with the backing node for the
  /// existing entity (whose type may differ from this entity's type).
  ///
  /// If [followTailLink] is true and the result node is a link, this will
  /// resolve it to its target prior to returning it.
  @protected
  Node? internalCreateSync({
    required Node? createChild(DirectoryNode parent, bool isFinalSegment),
    bool followTailLink = false,
    bool visitLinks = false,
  }) {
    return fileSystem.findNode(
      path,
      followTailLink: followTailLink,
      visitLinks: visitLinks,
      segmentVisitor: (
        DirectoryNode parent,
        String childName,
        Node? child,
        int currentSegment,
        int finalSegment,
      ) {
        if (child == null) {
          assert(!parent.children.containsKey(childName));
          child = createChild(parent, currentSegment == finalSegment);
          if (child != null) {
            parent.children[childName] = child;
          }
        }
        return child;
      },
    );
  }

  /// Helper method for subclasses wishing to synchronously rename this entity.
  /// This method will look for an existing file system entity at the location
  /// identified by [newPath], and if it finds an existing entity, it will check
  /// the following:
  ///
  /// - If the entity is of a different type than this entity, the operation
  ///   will fail, and a [io.FileSystemException] will be thrown.
  /// - If the caller has specified [validateOverwriteExistingEntity], then that
  ///   method will be invoked and passed the node backing of the existing
  ///   entity that would overwritten by the rename action. That callback is
  ///   expected to throw a [io.FileSystemException] if overwriting the existing
  ///   entity is not allowed.
  ///
  /// If the previous two checks pass, or if there was no existing entity at
  /// the specified location, this will perform the rename.
  ///
  /// If [newPath] cannot be traversed to because its directory does not exist,
  /// a [io.FileSystemException] will be thrown.
  ///
  /// If [followTailLink] is true and there is an existing link at the location
  /// identified by [newPath], this will resolve the link to its target prior
  /// to running the validation checks above.
  ///
  /// If [checkType] is specified, it will be used to validate that the file
  /// system entity that exists at [path] is of the expected type. By default,
  /// [defaultCheckType] is used to perform this validation.
  @protected
  FileSystemEntity internalRenameSync<T extends Node>(
    String newPath, {
    RenameOverwriteValidator<T>? validateOverwriteExistingEntity,
    bool followTailLink = false,
    utils.TypeChecker? checkType,
  }) {
    Node node = backing;
    (checkType ?? defaultCheckType)(node);
    fileSystem.findNode(
      newPath,
      segmentVisitor: (
        DirectoryNode parent,
        String childName,
        Node? child,
        int currentSegment,
        int finalSegment,
      ) {
        if (currentSegment == finalSegment) {
          if (child != null) {
            if (followTailLink) {
              FileSystemEntityType childType = child.stat.type;
              if (childType != FileSystemEntityType.notFound) {
                utils.checkType(expectedType, child.stat.type, () => newPath);
              }
            } else {
              utils.checkType(expectedType, child.type, () => newPath);
            }
            if (validateOverwriteExistingEntity != null) {
              validateOverwriteExistingEntity(child as T);
            }
            parent.children.remove(childName);
          }
          node.parent.children.remove(basename);
          parent.children[childName] = node;
          node.parent = parent;
        }
        return child;
      },
    );
    return clone(newPath);
  }

  /// Deletes this entity from the node tree.
  ///
  /// If [checkType] is specified, it will be used to validate that the file
  /// system entity that exists at [path] is of the expected type. By default,
  /// [defaultCheckType] is used to perform this validation.
  @protected
  void internalDeleteSync({
    bool recursive = false,
    utils.TypeChecker? checkType,
  }) {
    Node node = backing;
    if (!recursive) {
      if (node is DirectoryNode && node.children.isNotEmpty) {
        throw common.directoryNotEmpty(path);
      }
      (checkType ?? defaultCheckType)(node);
    }
    // Once we remove this reference, the node and all its children will be
    // garbage collected; we don't need to explicitly delete all children in
    // the recursive:true case.
    node.parent.children.remove(basename);
  }

  /// Creates a new entity with the same type as this entity but with the
  /// specified path.
  @protected
  FileSystemEntity clone(String path);
}
