// 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, () => 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({
    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);
            }
            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);
}
