// 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;
  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, f2fs_super_block* 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(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;

  info = new f2fs_super_block();
  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) {
  f2fs_sb_info& sbi = fs->SbInfo();

  if (!page)
    return ZX_OK;

  ZX_ASSERT(page->host == nullptr);
  ZX_ASSERT(page->host_nid == F2FS_NODE_INO(&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) {
  f2fs_sb_info& sbi = fs->SbInfo();

  if (!page)
    return ZX_OK;

  ZX_ASSERT(page->host == nullptr);
  ZX_ASSERT(page->host_nid == F2FS_META_INO(&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
