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