// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_STORAGE_LIB_VFS_CPP_FUCHSIA_VFS_H_
#define SRC_STORAGE_LIB_VFS_CPP_FUCHSIA_VFS_H_

#include <fidl/fuchsia.fs/cpp/common_types.h>
#include <fidl/fuchsia.io/cpp/common_types.h>
#include <fidl/fuchsia.io/cpp/natural_types.h>
#include <fidl/fuchsia.io/cpp/wire.h>
#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/wire/channel.h>
#include <lib/fit/function.h>
#include <lib/sync/completion.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>
#include <lib/zx/result.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/time.h>
#include <zircon/types.h>

#include <atomic>
#include <cstdint>
#include <memory>
#include <string>
#include <string_view>
#include <utility>

#include <fbl/intrusive_hash_table.h>
#include <fbl/ref_ptr.h>

#include "src/storage/lib/vfs/cpp/vfs.h"
#include "src/storage/lib/vfs/cpp/vfs_types.h"
#include "src/storage/lib/vfs/cpp/vnode.h"

namespace fs {

namespace internal {
class Connection;
class DirectoryConnection;
}  // namespace internal

// An internal version of fuchsia_io::wire::FilesystemInfo with a simpler API and default
// initializers. See that FIDL struct for documentation.
struct FilesystemInfo {
  uint64_t total_bytes = 0;
  uint64_t used_bytes = 0;
  uint64_t total_nodes = 0;
  uint64_t used_nodes = 0;
  uint64_t free_shared_pool_bytes = 0;
  uint64_t fs_id = 0;
  uint32_t block_size = 0;
  uint32_t max_filename_size = 0;
  fuchsia_fs::VfsType fs_type = fuchsia_fs::VfsType::Unknown();
  std::string name;  // Length must be less than MAX_FS_NAME_BUFFER.

  // To ensure global uniqueness, filesystems should create and maintain an event object. The koid
  // of this object is guaranteed unique in the system and is used for the filesystem ID. This
  // function extracts the koid of the given event object and sets it as the filesystem ID.
  void SetFsId(const zx::event& event);

  // Writes this object's values to the given FIDL object.
  fuchsia_io::wire::FilesystemInfo ToFidl() const;
};

// Vfs specialization that adds Fuchsia-specific
class FuchsiaVfs : public Vfs {
 private:
  friend class internal::DirectoryConnection;  // To allow access to ServeResult

  // To deal with the lifetime issues with connections, we roll our own (limited) shared/weak
  // pointers.  We can't easily use shared_ptr because that would involve changing all the clients,
  // or would incur some overheads that we don't need.  Connections cannot be terminated
  // synchronously (FIDL doesn't provide a synchronous unbind), so we have to allow connections to
  // outlive the VFS.  To avoid connections making bad calls into the VFS instance after it has been
  // destroyed, connections hold weak references to the VFS instance and upgrade when they need to.
  // The VFS instance will block destruction whilst there are strong references.  This Ref struct
  // stores the reference counts and can outlive the VFS instance.  When there are no strong or weak
  // references the Ref instance is destroyed.
  struct Ref {
    std::atomic<int> strong_count;
    std::atomic<int> weak_count;
    FuchsiaVfs* vfs;
  };

 public:
  class SharedPtr {
   public:
    SharedPtr(const SharedPtr& other) { *this = other; }
    SharedPtr& operator=(const SharedPtr& other);
    ~SharedPtr() { Reset(); }
    void Reset();

    FuchsiaVfs& operator*() const { return *vfs_; }
    FuchsiaVfs* operator->() const { return vfs_; }
    explicit operator bool() const { return !!vfs_; }
    FuchsiaVfs* get() const { return vfs_; }

   private:
    friend class FuchsiaVfs;

    // Adopts a strong reference.
    explicit SharedPtr(FuchsiaVfs* vfs) : vfs_(vfs) {}

    FuchsiaVfs* vfs_ = nullptr;
  };

  class WeakPtr {
   public:
    explicit WeakPtr(FuchsiaVfs* vfs) : ref_(vfs->ref_) { ref_->weak_count.fetch_add(1); }
    explicit WeakPtr(const SharedPtr& ptr) : ref_(ptr->ref_) { ref_->weak_count.fetch_add(1); }
    WeakPtr(const WeakPtr&) = delete;
    WeakPtr& operator=(const WeakPtr&) = delete;
    ~WeakPtr() {
      // The last weak count also means no more strong counts because we hold an implicit weak
      // reference whilst there are strong references.
      if (ref_->weak_count.fetch_sub(1) == 1)
        delete ref_;
    }
    SharedPtr Upgrade() const;

   private:
    friend class FuchsiaVfs;

    // Adopts a weak reference.
    explicit WeakPtr(Ref* ref) : ref_(ref) {}

    Ref* ref_;
  };

  explicit FuchsiaVfs(async_dispatcher_t* dispatcher = nullptr);

  // Not copyable or movable
  FuchsiaVfs(const FuchsiaVfs&) = delete;
  FuchsiaVfs& operator=(const FuchsiaVfs&) = delete;

  ~FuchsiaVfs() override;

  using ShutdownCallback = fit::callback<void(zx_status_t status)>;
  using CloseAllConnectionsForVnodeCallback = fit::callback<void()>;

  // Identifies if the filesystem is in the process of terminating. May be checked by active
  // connections, which, upon reading new port packets, should ignore them and close immediately.
  bool IsTerminating() const { return is_terminating_; }

  // Vfs overrides.
  zx_status_t Unlink(fbl::RefPtr<Vnode> vn, std::string_view name, bool must_be_dir) override
      __TA_EXCLUDES(vfs_lock_);

  void TokenDiscard(zx::event ios_token) __TA_EXCLUDES(vfs_lock_);
  zx_status_t VnodeToToken(fbl::RefPtr<Vnode> vn, zx::event* ios_token, zx::event* out)
      __TA_EXCLUDES(vfs_lock_);
  zx_status_t Link(zx::event token, fbl::RefPtr<Vnode> oldparent, std::string_view oldStr,
                   std::string_view newStr) __TA_EXCLUDES(vfs_lock_);
  zx_status_t Rename(zx::event token, fbl::RefPtr<Vnode> oldparent, std::string_view oldStr,
                     std::string_view newStr) __TA_EXCLUDES(vfs_lock_);

  // Provides the implementation for fuchsia.io.Directory.QueryFilesystem().
  // This default implementation returns ZX_ERR_NOT_SUPPORTED.
  virtual zx::result<FilesystemInfo> GetFilesystemInfo() __TA_EXCLUDES(vfs_lock_);

  async_dispatcher_t* dispatcher() const { return dispatcher_; }
  void SetDispatcher(async_dispatcher_t* dispatcher);

  // Begins serving VFS messages over the specified channel. The protocol to use will be determined
  // by the intersection of the protocols requested in |options| and those supported by |vnode|.
  // |server_end| usually speaks a protocol that composes |fuchsia.io/Node|, but may speak an
  // arbitrary arbitrary protocol for service connections.
  //
  // On failure, |server_end| will be closed with an epitaph matching the returned error.
  //
  // *NOTE*: |vnode| must be opened before calling this function, and will be automatically closed
  // on failure. This does not apply to node reference connections, which should not open |vnode|.
  // TODO(https://fxbug.dev/324080864): Remove this method when we no longer need to support Open1.
  zx_status_t ServeDeprecated(const fbl::RefPtr<Vnode>& vnode, zx::channel server_end,
                              DeprecatedOptions options) __TA_EXCLUDES(vfs_lock_);

  // Begins serving VFS messages over the specified channel. The protocol to use will be determined
  // by the intersection of the protocols requested in |flags| and those supported by |vnode|.
  // The connection rights will be set to the |fuchsia.io/Flags.PERM_*| bits present in |flags|.
  // |server_end| usually speaks a protocol that composes |fuchsia.io/Node|, but may speak an
  // arbitrary arbitrary protocol for service connections.
  //
  // On failure, |channel| will be closed with an epitaph matching the returned status.
  zx_status_t Serve(fbl::RefPtr<Vnode> vn, zx::channel channel, fuchsia_io::Flags flags);

  // Serves a Vnode over the specified channel (used for creating new filesystems); the
  // Vnode must be a directory.
  zx_status_t ServeDirectory(fbl::RefPtr<Vnode> vn,
                             fidl::ServerEnd<fuchsia_io::Directory> server_end,
                             fuchsia_io::Rights rights);

  // Convenience wrapper over |ServeDirectory| with maximum rights.
  zx_status_t ServeDirectory(fbl::RefPtr<Vnode> vn,
                             fidl::ServerEnd<fuchsia_io::Directory> server_end) {
    return ServeDirectory(std::move(vn), std::move(server_end), fuchsia_io::Rights::kMask);
  }

  // Closes all connections to a Vnode and calls |callback| after all connections are closed. The
  // caller must ensure that no new connections or transactions are created during this point.
  virtual void CloseAllConnectionsForVnode(const Vnode& node,
                                           CloseAllConnectionsForVnodeCallback callback) = 0;

  bool IsTokenAssociatedWithVnode(zx::event token) __TA_EXCLUDES(vfs_lock_);

 protected:
  // Unmounts the underlying filesystem. The result of shutdown is delivered via calling |closure|.
  //
  // |Shutdown| may be synchronous or asynchronous. The closure may be invoked before or after
  // |Shutdown| returns.
  virtual void Shutdown(ShutdownCallback closure) = 0;

  // Serve |open_result| using negotiated protocol and specified |rights|. On failure, if
  // |object_request| was not consumed, the caller should close it with an epitaph.
  //
  // *NOTE*: |rights| and |flags| are ignored for services.
  zx::result<> ServeResult(OpenResult open_result, fuchsia_io::Rights rights,
                           zx::channel& object_request, fuchsia_io::Flags flags,
                           const fuchsia_io::wire::Options& options);

  // On success, starts handling requests for |vnode| over |server_end|. On failure, callers are
  // responsible for closing |server_end|.
  zx_status_t ServeImpl(fbl::RefPtr<Vnode> vn, zx::channel& server_end, fuchsia_io::Flags flags);

  // On success, starts handling requests for |vnode| over |server_end|. On failure, callers are
  // responsible for closing |vnode| and |server_end|.
  zx_status_t ServeDeprecatedImpl(const fbl::RefPtr<Vnode>& vnode, zx::channel& server_end,
                                  DeprecatedOptions options) __TA_EXCLUDES(vfs_lock_);

  // Starts FIDL message dispatching on |channel|, at the same time starts to manage the lifetime of
  // |connection|. Consumes |channel| on success. On error, callers must close the associated vnode.
  virtual zx::result<> RegisterConnection(std::unique_ptr<internal::Connection> connection,
                                          zx::channel& channel) = 0;

  // Indicates this VFS instance is soon to be destroyed.  After calling this, `WaitTillDone` can be
  // called to wait until there are no strong references remaining.  It is not safe to call this
  // more than once.
  void WillDestroy() {
    ZX_ASSERT(!is_terminating_);
    is_terminating_.store(true);
    // Return the strong count taken in the constructor.
    SharedPtr strong(this);
  }

  // Waits till there are no strong references.
  void WaitTillDone() { sync_completion_wait(&done_, ZX_TIME_INFINITE); }

 private:
  zx_status_t TokenToVnode(zx::event token, fbl::RefPtr<Vnode>* out) __TA_REQUIRES(vfs_lock_);

  fbl::HashTable<zx_koid_t, std::unique_ptr<VnodeToken>> vnode_tokens_;

  async_dispatcher_t* dispatcher_ = nullptr;

  std::atomic<bool> is_terminating_ = false;

  // Signalled when there are no more strong references.
  sync_completion_t done_;

  // Holds the reference counts.
  Ref* ref_;
};

}  // namespace fs

#endif  // SRC_STORAGE_LIB_VFS_CPP_FUCHSIA_VFS_H_
