// 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:meta/meta.dart';
import 'package:path/path.dart' as p;

import '../io.dart' as io;

import 'directory.dart';
import 'file.dart';
import 'file_system_entity.dart';
import 'link.dart';

/// A generic representation of a file system.
///
/// Note that this class uses `dart:io` only inasmuch as it deals in the types
/// exposed by the `dart:io` library. Subclasses should document their level of
/// dependence on the library (and the associated implications of using that
/// implementation in the browser).
abstract class FileSystem {
  /// Creates a new `FileSystem`.
  const FileSystem();

  /// Returns a reference to a [Directory] at [path].
  ///
  /// [path] can be either a [`String`], a [`Uri`], or a [`FileSystemEntity`].
  Directory directory(dynamic path);

  /// Returns a reference to a [File] at [path].
  ///
  /// [path] can be either a [`String`], a [`Uri`], or a [`FileSystemEntity`].
  File file(dynamic path);

  /// Returns a reference to a [Link] at [path].
  ///
  /// [path] can be either a [`String`], a [`Uri`], or a [`FileSystemEntity`].
  Link link(dynamic path);

  /// An object for manipulating paths in this file system.
  p.Context get path;

  /// Gets the system temp directory.
  ///
  /// It is left to file system implementations to decide how to define the
  /// "system temp directory".
  Directory get systemTempDirectory;

  /// Creates a directory object pointing to the current working directory.
  Directory get currentDirectory;

  /// Sets the current working directory to the specified [path].
  ///
  /// The new value set can be either a [Directory] or a [String].
  ///
  /// Relative paths will be resolved by the underlying file system
  /// implementation (meaning it is up to the underlying implementation to
  /// decide whether to support relative paths).
  set currentDirectory(dynamic path);

  /// Asynchronously calls the operating system's stat() function on [path].
  /// Returns a Future which completes with a [io.FileStat] object containing
  /// the data returned by stat().
  /// If the call fails, completes the future with a [io.FileStat] object with
  /// .type set to FileSystemEntityType.NOT_FOUND and the other fields invalid.
  Future<io.FileStat> stat(String path);

  /// Calls the operating system's stat() function on [path].
  /// Returns a [io.FileStat] object containing the data returned by stat().
  /// If the call fails, returns a [io.FileStat] object with .type set to
  /// FileSystemEntityType.NOT_FOUND and the other fields invalid.
  io.FileStat statSync(String path);

  /// Checks whether two paths refer to the same object in the
  /// file system. Returns a [Future<bool>] that completes with the result.
  ///
  /// Comparing a link to its target returns false, as does comparing two links
  /// that point to the same target.  To check the target of a link, use
  /// Link.target explicitly to fetch it.  Directory links appearing
  /// inside a path are followed, though, to find the file system object.
  ///
  /// Completes the returned Future with an error if one of the paths points
  /// to an object that does not exist.
  Future<bool> identical(String path1, String path2);

  /// Synchronously checks whether two paths refer to the same object in the
  /// file system.
  ///
  /// Comparing a link to its target returns false, as does comparing two links
  /// that point to the same target.  To check the target of a link, use
  /// Link.target explicitly to fetch it.  Directory links appearing
  /// inside a path are followed, though, to find the file system object.
  ///
  /// Throws an error if one of the paths points to an object that does not
  /// exist.
  bool identicalSync(String path1, String path2);

  /// Tests if [FileSystemEntity.watch] is supported on the current system.
  bool get isWatchSupported;

  /// Finds the type of file system object that a [path] points to. Returns
  /// a Future<FileSystemEntityType> that completes with the result.
  ///
  /// [io.FileSystemEntityType.LINK] will only be returned if [followLinks] is
  /// `false`, and [path] points to a link
  ///
  /// If the [path] does not point to a file system object or an error occurs
  /// then [io.FileSystemEntityType.NOT_FOUND] is returned.
  Future<io.FileSystemEntityType> type(String path, {bool followLinks = true});

  /// Syncronously finds the type of file system object that a [path] points
  /// to. Returns a [io.FileSystemEntityType].
  ///
  /// [io.FileSystemEntityType.LINK] will only be returned if [followLinks] is
  /// `false`, and [path] points to a link
  ///
  /// If the [path] does not point to a file system object or an error occurs
  /// then [io.FileSystemEntityType.NOT_FOUND] is returned.
  io.FileSystemEntityType typeSync(String path, {bool followLinks = true});

  /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.FILE].
  Future<bool> isFile(String path) async =>
      await type(path) == io.FileSystemEntityType.file;

  /// Synchronously checks if [`type(path)`](type) returns
  /// [io.FileSystemEntityType.FILE].
  bool isFileSync(String path) =>
      typeSync(path) == io.FileSystemEntityType.file;

  /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.DIRECTORY].
  Future<bool> isDirectory(String path) async =>
      await type(path) == io.FileSystemEntityType.directory;

  /// Synchronously checks if [`type(path)`](type) returns
  /// [io.FileSystemEntityType.DIRECTORY].
  bool isDirectorySync(String path) =>
      typeSync(path) == io.FileSystemEntityType.directory;

  /// Checks if [`type(path)`](type) returns [io.FileSystemEntityType.LINK].
  Future<bool> isLink(String path) async =>
      await type(path) == io.FileSystemEntityType.link;

  /// Synchronously checks if [`type(path)`](type) returns
  /// [io.FileSystemEntityType.LINK].
  bool isLinkSync(String path) =>
      typeSync(path) == io.FileSystemEntityType.link;

  /// Gets the string path represented by the specified generic [path].
  ///
  /// [path] may be a [io.FileSystemEntity], a [String], or a [Uri].
  @protected
  String getPath(dynamic path) {
    if (path is io.FileSystemEntity) {
      return path.path;
    } else if (path is String) {
      return path;
    } else if (path is Uri) {
      return this.path.fromUri(path);
    } else {
      throw ArgumentError('Invalid type for "path": ${path?.runtimeType}');
    }
  }
}
