// Copyright 2020 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/factory/factoryfs/runner.h"

#include <fuchsia/fs/llcpp/fidl.h>
#include <lib/syslog/cpp/macros.h>

#include <fbl/auto_lock.h>

#include "src/lib/storage/vfs/cpp/pseudo_dir.h"
#include "src/storage/factory/factoryfs/query.h"

namespace factoryfs {

zx_status_t Runner::Create(async::Loop* loop, std::unique_ptr<BlockDevice> device,
                           MountOptions* options, std::unique_ptr<Runner>* out) {
  std::unique_ptr<Factoryfs> fs;
  zx_status_t status = Factoryfs::Create(loop->dispatcher(), std::move(device), options, &fs);
  if (status != ZX_OK) {
    return status;
  }
  auto runner = std::unique_ptr<Runner>(new Runner(loop, std::move(fs)));
  *out = std::move(runner);
  return ZX_OK;
}

void Runner::Shutdown(fs::Vfs::ShutdownCallback cb) {
  FX_LOGS(INFO) << "Shutdown";
  // Shutdown all external connections to Factoryfs.
  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.
      // factoryfs_ = 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_t Runner::ServeRoot(zx::channel root, ServeLayout layout) {
  fbl::RefPtr<fs::Vnode> vn;
  zx_status_t status = factoryfs_->OpenRootNode(&vn);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "mount failed; could not get root node";
    return status;
  }

  fbl::RefPtr<fs::Vnode> export_root;
  switch (layout) {
    case ServeLayout::kDataRootOnly:
      export_root = std::move(vn);
      break;
    case ServeLayout::kExportDirectory:
      auto outgoing = fbl::MakeRefCounted<fs::PseudoDir>();
      outgoing->AddEntry(kOutgoingDataRoot, std::move(vn));
      auto svc_dir = fbl::MakeRefCounted<fs::PseudoDir>();
      outgoing->AddEntry("svc", svc_dir);
      query_svc_ = fbl::MakeRefCounted<QueryService>(loop_->dispatcher(), factoryfs_.get(), this);
      svc_dir->AddEntry(fidl::DiscoverableProtocolName<fuchsia_fs::Query>, query_svc_);
      export_root = std::move(outgoing);
      break;
  }

  status = ServeDirectory(std::move(export_root), std::move(root));
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "mount failed; could not serve root directory";
    return status;
  }
  return ZX_OK;
}

Runner::Runner(async::Loop* loop, std::unique_ptr<Factoryfs> fs)
    : ManagedVfs(loop->dispatcher()), loop_(loop), factoryfs_(std::move(fs)) {}

bool Runner::IsReadonly() const { return true; }

}  // namespace factoryfs
