// 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 "f2fs.h"

#include <fcntl.h>
#include <inttypes.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/dispatcher.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/trace-provider/provider.h>
#include <lib/zx/event.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <zircon/assert.h>

#include <memory>

#include "src/lib/storage/vfs/cpp/pseudo_dir.h"
#include "src/lib/storage/vfs/cpp/trace.h"
#include "src/lib/uuid/uuid.h"
#include "zircon/errors.h"

namespace f2fs {

// This is the component's main class. It holds all of the component's state.
zx_status_t CreateBcache(std::unique_ptr<block_client::BlockDevice> device, bool* out_readonly,
                         std::unique_ptr<f2fs::Bcache>* out) {
  fuchsia_hardware_block_BlockInfo info;
  zx_status_t status = device->BlockGetInfo(&info);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Coult not access device info: " << status;
    return status;
  }

  uint64_t device_size = info.block_size * info.block_count;

  if (device_size == 0) {
    FX_LOGS(ERROR) << "Invalid device size";
    return status;
  }
  uint64_t block_count = device_size / kBlockSize;

  if (block_count >= std::numeric_limits<uint32_t>::max()) {
    FX_LOGS(ERROR) << "Block count overflow";
    return ZX_ERR_OUT_OF_RANGE;
  }

  return f2fs::Bcache::Create(std::move(device), static_cast<uint32_t>(block_count), out,
                              kBlockSize);
}

zx_status_t Mkfs(const MkfsOptions& options, std::unique_ptr<f2fs::Bcache> bc) {
  F2fsMkfs mkfs(std::move(bc), options);

  return mkfs.Mkfs();
}

zx_status_t Fsck(const MountOptions& options, std::unique_ptr<f2fs::Bcache> bc) { return ZX_OK; }

F2fs::F2fs(std::unique_ptr<f2fs::Bcache> bc, SuperBlock* sb, const MountOptions& mount_options)
    : bc_(std::move(bc)), mount_options_(mount_options) {
  raw_sb_ = std::unique_ptr<SuperBlock>(sb);

  zx::event event;
  if (zx_status_t status = zx::event::create(0, &event); status == ZX_OK) {
    zx_info_handle_basic_t info;
    if (status = event.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
        status == ZX_OK) {
      fs_id_ = info.koid;
    }
  }
}

F2fs::~F2fs() { vnode_table_.clear(); }

zx_status_t LoadSuperblock(f2fs::Bcache* bc, SuperBlock* out_info) {
  char buf[8192];

  if (zx_status_t status = bc->Readblk(kSuperblockStart, buf); status != ZX_OK) {
    FX_LOGS(ERROR) << "could not read info block.";
    return status;
  }

  memcpy(out_info, buf + 1024, sizeof(SuperBlock));

  return ZX_OK;
}

zx_status_t F2fs::Create(std::unique_ptr<f2fs::Bcache> bc, const MountOptions& options,
                         std::unique_ptr<F2fs>* out) {
  SuperBlock* info;

  info = new SuperBlock();
  if (zx_status_t status = LoadSuperblock(bc.get(), info); status != ZX_OK) {
    return status;
  }

  *out = std::unique_ptr<F2fs>(new F2fs(std::move(bc), info, options));

  return ZX_OK;
}

zx_status_t F2fs::FindVnode(fbl::RefPtr<VnodeF2fs>* out, ino_t ino) {
  fbl::RefPtr<VnodeF2fs> vn;
  fbl::AutoLock lock(&vnode_table_lock_);
  auto rawVn = vnode_table_.find(ino);

  if (rawVn.IsValid()) {
    vn = fbl::MakeRefPtrUpgradeFromRaw(rawVn.CopyPointer(), vnode_table_lock_);
    if (vn == nullptr) {
      vnode_table_.erase(ino);
    }

    *out = std::move(vn);

    return ZX_OK;
  }

  return ZX_ERR_NOT_FOUND;
}

void F2fs::InsertVnode(VnodeF2fs* vn) {
  fbl::AutoLock lock(&vnode_table_lock_);
  fbl::AutoLock lock_vn(&vn->v_lock_);
  vnode_table_.insert(vn);
}

void F2fs::EraseVnodeFromTable(VnodeF2fs* vn) {
  fbl::AutoLock lock(&vnode_table_lock_);
  fbl::AutoLock lock_vn(&vn->v_lock_);
  vnode_table_.erase(*vn);
}

zx_status_t CreateFsAndRoot(const MountOptions& mount_options, async_dispatcher_t* dispatcher,
                            std::unique_ptr<f2fs::Bcache> bcache, zx::channel mount_channel,
                            fbl::Closure on_unmount, ServeLayout serve_layout) {
  TRACE_DURATION("f2fs", "CreateFsAndRoot");
  f2fs::MountOptions options = mount_options;

  std::unique_ptr<F2fs> fs;
  if (zx_status_t status = F2fs::Create(std::move(bcache), options, &fs); status != ZX_OK) {
    FX_LOGS(ERROR) << "failed to create filesystem object " << status;
    return status;
  }

  if (zx_status_t ret = fs->FillSuper(); ret != ZX_OK) {
    std::cout << "FillSuper error " << ret << std::endl;
    return ret;
  }

  fbl::RefPtr<VnodeF2fs> data_root;
  if (zx_status_t status = VnodeF2fs::Vget(fs.get(), fs->RawSb().root_ino, &data_root);
      status != ZX_OK) {
    FX_LOGS(ERROR) << "cannot find root inode: " << status;
    return status;
  }

  __UNUSED auto r = fs.release();

  F2fs* vfs = data_root->Vfs();

  vfs->SetUnmountCallback(std::move(on_unmount));
  vfs->SetDispatcher(dispatcher);

  fbl::RefPtr<fs::Vnode> export_root;
  switch (serve_layout) {
    case ServeLayout::kDataRootOnly:
      export_root = std::move(data_root);
      break;
    case ServeLayout::kExportDirectory:
      auto outgoing = fbl::MakeRefCounted<fs::PseudoDir>();
      outgoing->AddEntry("root", std::move(data_root));
      export_root = std::move(outgoing);
      break;
  }

  return vfs->ServeDirectory(std::move(export_root), std::move(mount_channel));
}

zx_status_t Mount(const MountOptions& options, std::unique_ptr<f2fs::Bcache> bc) {
  zx::channel outgoing_server = zx::channel(zx_take_startup_handle(PA_DIRECTORY_REQUEST));
  zx::channel root_server = zx::channel(zx_take_startup_handle(FS_HANDLE_ROOT_ID));

  if (outgoing_server.is_valid() && root_server.is_valid()) {
    FX_LOGS(ERROR) << "both PA_DIRECTORY_REQUEST and FS_HANDLE_ROOT_ID provided - need one or the "
                      "other.";
    return ZX_ERR_BAD_STATE;
  }

  zx::channel export_root;
  f2fs::ServeLayout serve_layout;
  if (outgoing_server.is_valid()) {
    export_root = std::move(outgoing_server);
    serve_layout = f2fs::ServeLayout::kExportDirectory;
  } else if (root_server.is_valid()) {
    export_root = std::move(root_server);
    serve_layout = f2fs::ServeLayout::kDataRootOnly;
  } else {
    FX_LOGS(ERROR) << "could not get startup handle to serve on";
    return ZX_ERR_BAD_STATE;
  }

  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  trace::TraceProviderWithFdio trace_provider(loop.dispatcher());

  auto on_unmount = [&loop]() {
    loop.Quit();
    FX_LOGS(WARNING) << "Unmounted";
  };

  zx_status_t status = CreateFsAndRoot(options, loop.dispatcher(), std::move(bc),
                                       std::move(export_root), std::move(on_unmount), serve_layout);
  if (status != ZX_OK) {
    return -1;
  }

  ZX_ASSERT(loop.Run() == ZX_ERR_CANCELED);

  return ZX_OK;
}

void Sync(SyncCallback closure) {
  if (closure)
    closure(ZX_OK);
}

void F2fs::Shutdown(fs::Vfs::ShutdownCallback cb) {
  ManagedVfs::Shutdown([this, cb = std::move(cb)](zx_status_t status) mutable {
    Sync([this, cb = std::move(cb)](zx_status_t) mutable {
      async::PostTask(dispatcher(), [this, cb = std::move(cb)]() mutable {
        auto on_unmount = std::move(on_unmount_);

        PutSuper();

        // Explicitly delete this (rather than just letting the memory release when
        // the process exits) to ensure that the block device's fifo has been
        // closed.
        delete this;

        // Identify to the unmounting channel that teardown is complete.
        cb(ZX_OK);

        // Identify to the unmounting thread that teardown is complete.
        if (on_unmount) {
          on_unmount();
        }
      });
    });
  });
}

zx_status_t FlushDirtyNodePage(F2fs* fs, Page* page) {
  SbInfo& sbi = fs->GetSbInfo();

  if (!page)
    return ZX_OK;

  ZX_ASSERT(page->host == nullptr);
  ZX_ASSERT(page->host_nid == NodeIno(&sbi));

  if (zx_status_t ret = fs->Nodemgr().F2fsWriteNodePage(page, nullptr); ret != ZX_OK) {
    std::cout << "Node page write error " << ret << std::endl;
    return ret;
  }

  return ZX_OK;
}

zx_status_t FlushDirtyMetaPage(F2fs* fs, Page* page) {
  SbInfo& sbi = fs->GetSbInfo();

  if (!page)
    return ZX_OK;

  ZX_ASSERT(page->host == nullptr);
  ZX_ASSERT(page->host_nid == MetaIno(&sbi));

  if (zx_status_t ret = fs->F2fsWriteMetaPage(page, nullptr); ret != ZX_OK) {
    std::cout << "Meta page write error " << ret << std::endl;
    return ret;
  }

  return ZX_OK;
}

zx_status_t FlushDirtyDataPage(F2fs* fs, Page* page) {
  if (!page)
    return ZX_OK;

  ZX_ASSERT(page->host != nullptr);

  VnodeF2fs* vnode = static_cast<VnodeF2fs*>(page->host);

  if (zx_status_t ret = vnode->WriteDataPageReq(page, nullptr); ret != ZX_OK) {
    std::cout << "Data page write error " << ret << std::endl;
    return ret;
  }

  return ZX_OK;
}

}  // namespace f2fs
