// 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 void RenameOverwriteValidator<T extends Node>(T existingNode);

/// Base class for all in-memory file system entity types.
abstract class MemoryFileSystemEntity implements FileSystemEntity {
  @override
  final NodeBasedFileSystem fileSystem;

  @override
  final String path;

  /// Constructor for subclasses.
  const MemoryFileSystemEntity(this.fileSystem, this.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 new 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 new 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 => new 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.NOT_FOUND) {
                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);
}
