// 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.

#include "src/storage/blobfs/component_runner.h"

#include <fidl/fuchsia.fs.startup/cpp/wire.h>
#include <fidl/fuchsia.fs/cpp/wire.h>
#include <fidl/fuchsia.update.verify/cpp/wire.h>
#include <lib/inspect/service/cpp/service.h>
#include <lib/syslog/cpp/macros.h>

#include "src/lib/storage/vfs/cpp/remote_dir.h"
#include "src/storage/blobfs/service/admin.h"
#include "src/storage/blobfs/service/health_check.h"
#include "src/storage/blobfs/service/lifecycle.h"
#include "src/storage/blobfs/service/startup.h"

namespace blobfs {

ComponentRunner::ComponentRunner(async::Loop& loop) : fs::PagedVfs(loop.dispatcher()), loop_(loop) {
  outgoing_ = fbl::MakeRefCounted<fs::PseudoDir>(this);
  auto startup = fbl::MakeRefCounted<fs::PseudoDir>(this);
  outgoing_->AddEntry("startup", startup);

  FX_LOGS(INFO) << "setting up startup service";
  auto startup_svc = fbl::MakeRefCounted<StartupService>(
      loop_.dispatcher(), [this](std::unique_ptr<BlockDevice> device, const MountOptions& options) {
        FX_LOGS(INFO) << "configure callback is called";
        zx::status<> status = Configure(std::move(device), options);
        if (status.is_error()) {
          FX_LOGS(ERROR) << "Could not configure blobfs: " << status.status_string();
        }
        return status;
      });
  startup->AddEntry(fidl::DiscoverableProtocolName<fuchsia_fs_startup::Startup>, startup_svc);
}

ComponentRunner::~ComponentRunner() {
  // Inform PagedVfs so that it can stop threads that might call out to blobfs.
  TearDown();
}

void ComponentRunner::RemoveSystemDrivers(fit::callback<void(zx_status_t)> callback) {
  // If we don't have a connection to Driver Manager, just return ZX_OK.
  if (!driver_admin_.is_valid()) {
    FX_LOGS(INFO) << "blobfs doesn't have driver manager connection; assuming test environment";
    callback(ZX_OK);
    return;
  }

  using Unregister = fuchsia_device_manager::Administrator::UnregisterSystemStorageForShutdown;
  driver_admin_->UnregisterSystemStorageForShutdown().ThenExactlyOnce(
      [callback = std::move(callback)](fidl::WireUnownedResult<Unregister>& result) mutable {
        if (!result.ok()) {
          callback(result.status());
          return;
        }
        callback(result.value().status);
      });
}

void ComponentRunner::Shutdown(fs::FuchsiaVfs::ShutdownCallback cb) {
  TRACE_DURATION("blobfs", "ComponentRunner::Shutdown");
  // Before shutting down blobfs, we need to try to shut down any drivers that are running out of
  // it, because right now those drivers don't have an explicit dependency on blobfs in the
  // component hierarchy so they don't get shut down before us yet.
  RemoveSystemDrivers([this, cb = std::move(cb)](zx_status_t status) mutable {
    // If we failed to notify the driver stack about the impending shutdown, log a warning, but
    // continue the shutdown.
    if (status != ZX_OK) {
      FX_LOGS(WARNING) << "failed to send shutdown signal to driver manager: "
                       << zx_status_get_string(status);
    }
    // Shutdown all external connections to blobfs.
    ManagedVfs::Shutdown([this, cb = std::move(cb)](zx_status_t status) mutable {
      async::PostTask(dispatcher(), [this, status, cb = std::move(cb)]() mutable {
        // Manually destroy the filesystem. The promise of Shutdown is that no
        // connections are active, and destroying the Runner object
        // should terminate all background workers.
        blobfs_ = nullptr;

        // Tell the mounting thread that the filesystem has terminated.
        loop_.Quit();

        // Tell the unmounting channel that we've completed teardown. This *must* be the last thing
        // we do because after this, the caller can assume that it's safe to destroy the runner.
        cb(status);
      });
    });
  });
}

zx::status<fs::FilesystemInfo> ComponentRunner::GetFilesystemInfo() {
  return blobfs_->GetFilesystemInfo();
}

zx::status<> ComponentRunner::ServeRoot(
    fidl::ServerEnd<fuchsia_io::Directory> root,
    fidl::ServerEnd<fuchsia_process_lifecycle::Lifecycle> lifecycle,
    fidl::ClientEnd<fuchsia_device_manager::Administrator> driver_admin_client,
    zx::resource vmex_resource) {
  LifecycleServer::Create(
      loop_.dispatcher(),
      [this](fs::FuchsiaVfs::ShutdownCallback cb) { this->Shutdown(std::move(cb)); },
      std::move(lifecycle));

  fidl::WireSharedClient<fuchsia_device_manager::Administrator> driver_admin;
  if (driver_admin_client.is_valid()) {
    driver_admin = fidl::WireSharedClient<fuchsia_device_manager::Administrator>(
        std::move(driver_admin_client), loop_.dispatcher());
  }
  driver_admin_ = std::move(driver_admin);

  // Make dangling endpoints for the root directory and the service directory. Creating the
  // endpoints and putting them into the filesystem tree has the effect of queuing incoming
  // requests until the server end of the endpoints is bound.
  auto svc_endpoints = fidl::CreateEndpoints<fuchsia_io::Directory>();
  if (svc_endpoints.is_error()) {
    FX_LOGS(ERROR) << "mount failed; could not create service directory endpoints";
    return svc_endpoints.take_error();
  }
  outgoing_->AddEntry("svc", fbl::MakeRefCounted<fs::RemoteDir>(std::move(svc_endpoints->client)));
  svc_server_end_ = std::move(svc_endpoints->server);
  auto root_endpoints = fidl::CreateEndpoints<fuchsia_io::Directory>();
  if (root_endpoints.is_error()) {
    FX_LOGS(ERROR) << "mount failed; could not create root directory endpoints";
    return root_endpoints.take_error();
  }
  outgoing_->AddEntry("root",
                      fbl::MakeRefCounted<fs::RemoteDir>(std::move(root_endpoints->client)));
  root_server_end_ = std::move(root_endpoints->server);

  vmex_resource_ = std::move(vmex_resource);
  zx_status_t status = ServeDirectory(outgoing_, std::move(root));
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "mount failed; could not serve root directory";
    return zx::error(status);
  }

  return zx::ok();
}

zx::status<> ComponentRunner::Configure(std::unique_ptr<BlockDevice> device,
                                        const MountOptions& options) {
  if (auto status = Init(); status.is_error()) {
    FX_LOGS(ERROR) << "configure failed; vfs init failed";
    return status.take_error();
  }

  auto blobfs_or = Blobfs::Create(loop_.dispatcher(), std::move(device), this, options,
                                  std::move(vmex_resource_));
  if (blobfs_or.is_error()) {
    FX_LOGS(ERROR) << "configure failed; could not create blobfs: " << blobfs_or.status_string();
    return blobfs_or.take_error();
  }
  blobfs_ = std::move(blobfs_or.value());
  SetReadonly(blobfs_->writability() != Writability::Writable);

  fbl::RefPtr<fs::Vnode> root;
  zx_status_t status = blobfs_->OpenRootNode(&root);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "configure failed; could not get root blob: " << zx_status_get_string(status);
    return zx::error(status);
  }

  status = ServeDirectory(std::move(root), std::move(root_server_end_));
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "configure failed; could not serve root directory: "
                   << zx_status_get_string(status);
    return zx::error(status);
  }

  // Specify to fall back to DeepCopy mode instead of Live mode (the default) on failures to send
  // a Frozen copy of the tree (e.g. if we could not create a child copy of the backing VMO).
  // This helps prevent any issues with querying the inspect tree while the filesystem is under
  // load, since snapshots at the receiving end must be consistent. See fxbug.dev/57330 for details.
  inspect::TreeHandlerSettings settings{.snapshot_behavior =
                                            inspect::TreeServerSendPreference::Frozen(
                                                inspect::TreeServerSendPreference::Type::DeepCopy)};

  auto inspect_tree = fbl::MakeRefCounted<fs::Service>(
      [connector = inspect::MakeTreeHandler(blobfs_->GetMetrics()->inspector(), loop_.dispatcher(),
                                            settings)](zx::channel chan) mutable {
        connector(fidl::InterfaceRequest<fuchsia::inspect::Tree>(std::move(chan)));
        return ZX_OK;
      });

  // Add the diagnostics directory straight to the outgoing directory. Nothing should be relying on
  // the diagnostics directory queuing incoming requests.
  auto diagnostics_dir = fbl::MakeRefCounted<fs::PseudoDir>(this);
  outgoing_->AddEntry("diagnostics", diagnostics_dir);
  diagnostics_dir->AddEntry(fuchsia::inspect::Tree::Name_, inspect_tree);

  auto svc_dir = fbl::MakeRefCounted<fs::PseudoDir>(this);

  svc_dir->AddEntry(fidl::DiscoverableProtocolName<fuchsia_update_verify::BlobfsVerifier>,
                    fbl::MakeRefCounted<HealthCheckService>(loop_.dispatcher(), *blobfs_));

  svc_dir->AddEntry(fidl::DiscoverableProtocolName<fuchsia_fs::Admin>,
                    fbl::MakeRefCounted<AdminService>(blobfs_->dispatcher(),
                                                      [this](fs::FuchsiaVfs::ShutdownCallback cb) {
                                                        this->Shutdown(std::move(cb));
                                                      }));

  status = ServeDirectory(std::move(svc_dir), std::move(svc_server_end_));
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "configure failed; could not serve svc dir: " << zx_status_get_string(status);
    return zx::error(status);
  }

  return zx::ok();
}

}  // namespace blobfs
