// 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 <fcntl.h>
#include <inttypes.h>
#include <lib/syslog/cpp/macros.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

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

#include <memory>

#include <lib/zx/event.h>
#include <zircon/assert.h>

#include <lib/async/dispatcher.h>

#include "zircon/errors.h"
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/trace-provider/provider.h>
#include "src/lib/storage/vfs/cpp/pseudo_dir.h"
#include "src/lib/storage/vfs/cpp/trace.h"

#include "f2fs.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 / kF2fsBlockSize;

  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,
                              kF2fsBlockSize);
}

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, f2fs_super_block* sb,
           const MountOptions& mount_options)
    : bc_(std::move(bc)), mount_options_(mount_options) {
  raw_sb_ = std::unique_ptr<f2fs_super_block>(sb);

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

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

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

  zx_status_t status;

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

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

  return ZX_OK;
}

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

  info = new f2fs_super_block();
  status = LoadSuperblock(bc.get(), info);
  if (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;
  zx_status_t status = F2fs::Create(std::move(bcache), options, &fs);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "failed to create filesystem object " << status;
    return status;
  }

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

  fbl::RefPtr<VnodeF2fs> data_root;
  status = VnodeF2fs::F2fsVget(fs.get(), fs->RawSb().root_ino, &data_root);
  if (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_);

        F2fsPutSuper();

        // 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) {
  f2fs_sb_info& sbi = fs->SbInfo();
  zx_status_t ret = ZX_OK;

  if (!page)
    return ret;

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

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

  return ret;
}

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

  if (!page)
    return ret;

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

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

  return ret;
}

zx_status_t FlushDirtyDataPage(F2fs* fs, Page* page) {
  zx_status_t ret = ZX_OK;

  if (!page)
    return ret;

  ZX_ASSERT(page->host != nullptr);

  VnodeF2fs* vnode = (VnodeF2fs*)page->host;
  ret = vnode->F2fsWriteDataPage(page, nullptr);
  if (ret) {
    std::cout << "Data page write error " << ret << std::endl;
  }

  return ret;
}

}  // namespace f2fs
