// Copyright 2019 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_FSHOST_FS_MANAGER_H_
#define SRC_STORAGE_FSHOST_FS_MANAGER_H_

#include <fuchsia/device/manager/llcpp/fidl.h>
#include <fuchsia/process/lifecycle/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/wait.h>
#include <lib/memfs/cpp/vnode.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>
#include <lib/zx/job.h>
#include <zircon/compiler.h>
#include <zircon/types.h>

#include <array>
#include <iterator>
#include <map>

#include <fs/vfs.h>

#include "src/lib/loader_service/loader_service.h"

// Used for fshost signals.
#include "delayed-outdir.h"
#include "fdio.h"
#include "fshost-boot-args.h"
#include "inspect-manager.h"
#include "metrics.h"
#include "registry.h"

namespace devmgr {

class BlockWatcher;

// FsManager owns multiple sub-filesystems, managing them within a top-level
// in-memory filesystem.
class FsManager {
 public:
  explicit FsManager(std::shared_ptr<FshostBootArgs> boot_args,
                     std::unique_ptr<FsHostMetrics> metrics);
  ~FsManager();

  zx_status_t Initialize(
      fidl::ServerEnd<::llcpp::fuchsia::io::Directory> dir_request,
      fidl::ServerEnd<::llcpp::fuchsia::process::lifecycle::Lifecycle> lifecycle_request,
      fidl::ClientEnd<::llcpp::fuchsia::device::manager::Administrator> driver_admin,
      std::shared_ptr<loader::LoaderServiceBase> loader, BlockWatcher& watcher);

  // TODO(fxbug.dev/39588): delete this
  // Starts servicing the delayed portion of the outgoing directory, called once
  // "/system" has been mounted.
  void FuchsiaStart() { delayed_outdir_.Start(); }

  // MountPoint is a possible location that a filesystem can be installed at.
  enum class MountPoint {
    kUnknown = 0,
    kBin,
    kData,
    kVolume,
    kSystem,
    kInstall,
    kBlob,
    kPkgfs,
    kFactory,
    kDurable,
  };

  // Returns the fully qualified for the given mount point.
  static const char* MountPointPath(MountPoint);

  constexpr static std::array<MountPoint, 9> kAllMountPoints{
      MountPoint::kBin,    MountPoint::kData,    MountPoint::kVolume,
      MountPoint::kSystem, MountPoint::kInstall, MountPoint::kBlob,
      MountPoint::kPkgfs,  MountPoint::kFactory, MountPoint::kDurable,
  };

  // Installs the filesystem with |root_directory| at |mount_point| (which must not already have an
  // installed filesystem).
  // |root_directory| should be a connection to a Directory, but this is not verified.
  zx_status_t InstallFs(MountPoint mount_point, zx::channel root_directory);

  // Stores |export_root_directory| for the filesystem installed at |mount_point|.
  // This must be called before any services are forwarded (e.g. |ForwardFsService()|).
  zx_status_t SetFsExportRoot(MountPoint mount_point, zx::channel export_root_directory);

  // Serves connection to the root directory ("/") on |server|.
  zx_status_t ServeRoot(fidl::ServerEnd<::llcpp::fuchsia::io::Directory> server);

  // Serves connection to the fshost directory (exporting the "fuchsia.fshost" services) on
  // |server|.
  zx_status_t ServeFshostRoot(zx::channel server) { return registry_.ServeRoot(std::move(server)); }

  // Asynchronously shut down all the filesystems managed by fshost and then signal the main thread
  // to exit. Calls |callback| when complete.
  void Shutdown(fit::function<void(zx_status_t)> callback);

  // Returns a pointer to the |FsHostMetrics| instance.
  FsHostMetrics* mutable_metrics() { return metrics_.get(); }

  // Flushes FsHostMetrics to cobalt.
  void FlushMetrics();

  std::shared_ptr<FshostBootArgs> boot_args() { return boot_args_; }

  bool IsShutdown();
  void WaitForShutdown();

  // Creates a new subdirectory in the fshost diagnostics directory by the name of
  // |diagnostics_dir_name|, which forwards the diagnostics dir exposed in the export root directory
  // of the given filesystem previously installed via |InstallFs()| at |point|.
  zx_status_t ForwardFsDiagnosticsDirectory(MountPoint point, const char* diagnostics_dir_name);

  // Creates a new subdirectory in the fshost svc directory by the name of
  // |service_name|, which forwards the service by the same name exposed in the outgoing service
  // directory of the given filesystem previously installed via |InstallFs()| at |point|.
  zx_status_t ForwardFsService(MountPoint point, const char* service_name);

 private:
  zx_status_t SetupOutgoingDirectory(fidl::ServerEnd<::llcpp::fuchsia::io::Directory> dir_request,
                                     std::shared_ptr<loader::LoaderServiceBase> loader,
                                     BlockWatcher& watcher);

  zx_status_t SetupLifecycleServer(
      fidl::ServerEnd<::llcpp::fuchsia::process::lifecycle::Lifecycle> lifecycle_request);

  struct MountNode {
    // Set by |InstallFs()|.
    zx::channel root_export_dir;
    fbl::RefPtr<fs::Vnode> root_directory;

    bool Installed() const { return root_export_dir.is_valid(); }
  };
  std::map<MountPoint, MountNode> mount_nodes_;

  // Tell driver_manager to remove all drivers living in storage. This must be called before
  // shutting down. `callback` will be called once all drivers living in storage have been
  // unbound and removed.
  void RemoveSystemDrivers(fit::callback<void(zx_status_t)> callback);

  // The Root VFS manages the following filesystems:
  // - The global root filesystem (including the mount points)
  // - "/tmp"
  std::unique_ptr<memfs::Vfs> root_vfs_;

  std::unique_ptr<async::Loop> global_loop_;
  fs::ManagedVfs outgoing_vfs_;

  // The base, root directory which serves the rest of the fshost.
  fbl::RefPtr<memfs::VnodeDir> global_root_;

  // Controls the external fshost vnode, as well as registration of filesystems
  // dynamically within the fshost.
  fshost::Registry registry_;

  // Keeps a collection of metrics being track at the FsHost level.
  std::unique_ptr<FsHostMetrics> metrics_;

  // Serves inspect data.
  InspectManager inspect_;

  // Used to lookup configuration options stored in fuchsia.boot.Arguments
  std::shared_ptr<devmgr::FshostBootArgs> boot_args_;

  // The outgoing service directory for fshost.
  fbl::RefPtr<fs::PseudoDir> svc_dir_;

  // TODO(fxbug.dev/39588): delete this
  // A RemoteDir in the outgoing directory that ignores requests until Start is
  // called on it.
  DelayedOutdir delayed_outdir_;

  // The diagnostics directory for the fshost inspect tree.
  // Each filesystem gets a subdirectory to host their own inspect tree.
  // Archivist will parse all the inspect trees found in this directory tree.
  fbl::RefPtr<fs::PseudoDir> diagnostics_dir_;

  std::mutex lock_;
  bool shutdown_called_ TA_GUARDED(lock_) = false;
  sync_completion_t shutdown_;
  fidl::Client<llcpp::fuchsia::device::manager::Administrator> driver_admin_;
};

}  // namespace devmgr

#endif  // SRC_STORAGE_FSHOST_FS_MANAGER_H_
