// Copyright 2016 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 <lib/syslog/cpp/macros.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include <zircon/device/vfs.h>
#include <zircon/time.h>

#include <cstdint>
#include <memory>
#include <string_view>

#include <fbl/algorithm.h>
#include <safemath/checked_math.h>

#include "src/lib/storage/vfs/cpp/trace.h"
#include "src/lib/storage/vfs/cpp/vfs_types.h"

#ifdef __Fuchsia__
#include <lib/fidl-utils/bind.h>
#include <zircon/syscalls.h>

#include <utility>

#include <fbl/auto_lock.h>
#endif

#include "src/storage/minfs/directory.h"
#include "src/storage/minfs/file.h"
#include "src/storage/minfs/minfs_private.h"
#include "src/storage/minfs/unowned_vmo_buffer.h"
#include "src/storage/minfs/vnode.h"

namespace minfs {

#ifdef __Fuchsia__

void VnodeMinfs::HandleFsSpecificMessage(fidl_incoming_msg_t* msg, fidl::Transaction* transaction) {
  fidl::WireDispatch<fuchsia_minfs::Minfs>(this, msg, transaction);
}

#endif  // __Fuchsia__

void VnodeMinfs::SetIno(ino_t ino) {
  ZX_DEBUG_ASSERT(ino_ == 0);
  ino_ = ino;
}

void VnodeMinfs::AddLink() {
  ZX_ASSERT_MSG(!add_overflow(inode_.link_count, 1, &inode_.link_count), "Exceeded max link count");
}

void VnodeMinfs::InodeSync(PendingWork* transaction, uint32_t flags) {
  // by default, c/mtimes are not updated to current time
  if (flags != kMxFsSyncDefault) {
    zx_time_t cur_time = GetTimeUTC();
    // update times before syncing
    if ((flags & kMxFsSyncMtime) != 0) {
      inode_.modify_time = cur_time;
    }
    if ((flags & kMxFsSyncCtime) != 0) {
      inode_.create_time = cur_time;
    }
  }

  fs_->InodeUpdate(transaction, ino_, &inode_);
}

// Delete all blocks (relative to a file) from "start" (inclusive) to the end of
// the file. Does not update mtime/atime.
zx_status_t VnodeMinfs::BlocksShrink(PendingWork* transaction, blk_t start) {
  VnodeMapper mapper(this);
  VnodeIterator iterator;
  zx_status_t status = iterator.Init(&mapper, transaction, start);
  if (status != ZX_OK)
    return status;
  uint64_t block_count = VnodeMapper::kMaxBlocks - start;
  while (block_count > 0) {
    uint64_t count;
    if (iterator.Blk() == 0) {
      count = iterator.GetContiguousBlockCount(block_count);
    } else {
      count = 1;
      DeleteBlock(transaction, static_cast<blk_t>(iterator.file_block()), iterator.Blk(),
                  /*indirect=*/false);
      zx_status_t status = iterator.SetBlk(0);
      if (status != ZX_OK)
        return status;
    }
    status = iterator.Advance(count);
    if (status != ZX_OK)
      return status;
    block_count -= count;
  }
  status = iterator.Flush();
  if (status != ZX_OK)
    return status;
  // Shrink the buffer backing the virtual indirect file.
  if (indirect_file_) {
    uint64_t indirect_block_pointers;
    if (start <= VnodeMapper::kIndirectFileStartBlock) {
      indirect_block_pointers = 0;
    } else if (start <= VnodeMapper::kDoubleIndirectFileStartBlock) {
      indirect_block_pointers = start - VnodeMapper::kIndirectFileStartBlock;
    } else {
      indirect_block_pointers = (start - VnodeMapper::kDoubleIndirectFileStartBlock) +
                                (kMinfsIndirect + kMinfsDoublyIndirect) * kMinfsDirectPerIndirect;
    }
    indirect_file_->Shrink(
        fbl::round_up(indirect_block_pointers * sizeof(blk_t), fs_->BlockSize()) /
        fs_->BlockSize());
  }
  return ZX_OK;
}

zx::status<LazyBuffer*> VnodeMinfs::GetIndirectFile() {
  if (!indirect_file_) {
    zx::status<std::unique_ptr<LazyBuffer>> buffer =
        LazyBuffer::Create(fs_->bc_.get(), "minfs-indirect-file", fs_->BlockSize());
    if (buffer.is_error())
      return buffer.take_error();
    indirect_file_ = std::move(buffer).value();
  }
  return zx::ok(indirect_file_.get());
}

#ifdef __Fuchsia__

// TODO(smklein): Even this hack can be optimized; a bitmap could be used to
// track all 'empty/read/dirty' blocks for each vnode, rather than reading
// the entire file.
//
// TODO(fxbug.dev/51589): Add init metrics.
zx_status_t VnodeMinfs::InitVmo() {
  TRACE_DURATION("minfs", "VnodeMinfs::InitVmo");
  if (vmo_.is_valid()) {
    return ZX_OK;
  }

  zx_status_t status;
  const size_t vmo_size = fbl::round_up(GetSize(), fs_->BlockSize());
  if ((status = zx::vmo::create(vmo_size, ZX_VMO_RESIZABLE, &vmo_)) != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to initialize vmo; error: " << status;
    return status;
  }
  vmo_size_ = vmo_size;

  zx_object_set_property(vmo_.get(), ZX_PROP_NAME, "minfs-inode", 11);

  if ((status = fs_->bc_->BlockAttachVmo(vmo_, &vmoid_)) != ZX_OK) {
    vmo_.reset();
    return status;
  }

  fs::BufferedOperationsBuilder builder;
  VnodeMapper mapper(this);
  VnodeIterator iterator;
  status = iterator.Init(&mapper, nullptr, 0);
  if (status != ZX_OK)
    return status;
  uint64_t block_count = vmo_size / fs_->BlockSize();
  while (block_count > 0) {
    blk_t block = iterator.Blk();
    uint64_t count = iterator.GetContiguousBlockCount(block_count);
    if (block) {
      fs_->ValidateBno(block);
      fs::internal::BorrowedBuffer buffer(vmoid_.get());
      builder.Add(storage::Operation{.type = storage::OperationType::kRead,
                                     .vmo_offset = iterator.file_block(),
                                     .dev_offset = block + fs_->Info().dat_block,
                                     .length = count},
                  &buffer);
    }
    status = iterator.Advance(count);
    if (status != ZX_OK)
      return status;
    block_count -= count;
  }
  status = fs_->GetMutableBcache()->RunRequests(builder.TakeOperations());
  ValidateVmoTail(GetSize());
  return status;
}

#endif

void VnodeMinfs::AllocateIndirect(PendingWork* transaction, blk_t* block) {
  ZX_DEBUG_ASSERT(transaction != nullptr);
  fs_->BlockNew(transaction, block);
  inode_.block_count++;
}

zx_status_t VnodeMinfs::BlockGetWritable(Transaction* transaction, blk_t n, blk_t* bno) {
  VnodeMapper mapper(this);
  VnodeIterator iterator;
  zx_status_t status = iterator.Init(&mapper, transaction, n);
  if (status != ZX_OK)
    return status;
  blk_t block = iterator.Blk();
  AcquireWritableBlock(transaction, n, block, &block);
  if (block != iterator.Blk()) {
    status = iterator.SetBlk(block);
    if (status != ZX_OK)
      return status;
  }
  *bno = block;
  return iterator.Flush();
}

zx_status_t VnodeMinfs::BlockGetReadable(blk_t n, blk_t* bno) {
  VnodeMapper mapper(this);
  zx::status<std::pair<blk_t, uint64_t>> mapping = mapper.MapToBlk(BlockRange(n, n + 1));
  if (mapping.is_error())
    return mapping.status_value();
  *bno = mapping.value().first;
  return ZX_OK;
}

zx_status_t VnodeMinfs::ReadExactInternal(PendingWork* transaction, void* data, size_t len,
                                          size_t off) {
  size_t actual;
  zx_status_t status = ReadInternal(transaction, data, len, off, &actual);
  if (status != ZX_OK) {
    return status;
  }
  if (actual != len) {
    return ZX_ERR_IO;
  }
  return ZX_OK;
}

zx_status_t VnodeMinfs::WriteExactInternal(Transaction* transaction, const void* data, size_t len,
                                           size_t off) {
  size_t actual;
  zx_status_t status =
      WriteInternal(transaction, static_cast<const uint8_t*>(data), len, off, &actual);
  if (status != ZX_OK) {
    return status;
  }
  if (actual != len) {
    return ZX_ERR_IO;
  }
  InodeSync(transaction, kMxFsSyncMtime);
  return ZX_OK;
}

zx_status_t VnodeMinfs::RemoveInodeLink(Transaction* transaction) {
  ZX_ASSERT(inode_.link_count > 0);

  // This effectively 'unlinks' the target node without deleting the direntry
  inode_.link_count--;
  if (IsDirectory()) {
    if (inode_.link_count == 1) {
      // Directories are initialized with two links, since they point
      // to themselves via ".". Thus, when they reach "one link", they
      // are only pointed to by themselves, and should be deleted.
      inode_.link_count--;
    }
  }

  if (IsUnlinked()) {
    // The open_count() needs to be read within the lock to make the compiler's checking happy,
    // but we don't actually need this lock and can run into recursive locking if we hold it for
    // the subsequent operations in this block.
    int oc;
    {
      std::lock_guard lock(mutex_);
      oc = open_count();
    }

    if (oc == 0) {
      // No need to flush/retain dirty cache or the reservations for unlinked
      // inode.
      DropCachedWrites();
      zx_status_t status = Purge(transaction);
      if (status != ZX_OK) {
        return status;
      }
    } else {
      fs_->AddUnlinked(transaction, this);
      if (IsDirectory()) {
        // If it's a directory, we need to remove the . and .. entries, which should be the only
        // entries.
        inode_.dirent_count = 0;
        zx_status_t status = TruncateInternal(transaction, 0);
        if (status != ZX_OK) {
          return status;
        }
      }
    }
  }

  InodeSync(transaction, kMxFsSyncMtime);
  return ZX_OK;
}

void VnodeMinfs::ValidateVmoTail(uint64_t inode_size) const {
#if defined(MINFS_PARANOID_MODE) && defined(__Fuchsia__)
  if (!vmo_.is_valid()) {
    return;
  }

  // Verify that everything not allocated to "inode_size" in the
  // last block is filled with zeroes.
  char buf[fs_->BlockSize()];
  const size_t vmo_size = fbl::round_up(inode_size, fs_->BlockSize());
  ZX_ASSERT(vmo_.read(buf, inode_size, vmo_size - inode_size) == ZX_OK);
  for (size_t i = 0; i < vmo_size - inode_size; i++) {
    ZX_ASSERT_MSG(buf[i] == 0, "vmo[%" PRIu64 "] != 0 (inode size = %u)\n", inode_size + i,
                  inode_size);
  }
#endif  // MINFS_PARANOID_MODE && __Fuchsia__
}

void VnodeMinfs::fbl_recycle() {
  {
    // Need to hold the lock to check open_count(), but be careful not to hold it across this class
    // getting deleted at the bottom of this function.
    std::lock_guard lock(mutex_);
    ZX_DEBUG_ASSERT(open_count() == 0);
  }
  if (!IsUnlinked()) {
    // If this node has not been purged already, remove it from the
    // hash map. If it has been purged; it will already be absent
    // from the map (and may have already been replaced with a new
    // node, if the inode has been re-used).
    fs_->VnodeRelease(this);
  }
  delete this;
}

VnodeMinfs::~VnodeMinfs() {
#ifdef __Fuchsia__
  // Detach the vmoids from the underlying block device,
  // so the underlying VMO may be released.
  size_t request_count = 0;
  block_fifo_request_t request[2];
  if (vmoid_.IsAttached()) {
    request[request_count].vmoid = vmoid_.TakeId();
    request[request_count].opcode = BLOCKIO_CLOSE_VMO;
    request_count++;
  }
  if (request_count) {
    fs_->bc_->GetDevice()->FifoTransaction(&request[0], request_count);
  }
#endif
  if (indirect_file_) {
    zx_status_t status = indirect_file_->Detach(fs_->bc_.get());
    ZX_DEBUG_ASSERT(status == ZX_OK);
  }
}

zx_status_t VnodeMinfs::Purge(Transaction* transaction) {
  {
    std::lock_guard lock(mutex_);
    ZX_DEBUG_ASSERT(open_count() == 0);
  }
  ZX_DEBUG_ASSERT(IsUnlinked());
  fs_->VnodeRelease(this);
  return fs_->InoFree(transaction, this);
}

zx_status_t VnodeMinfs::RemoveUnlinked() {
  ZX_ASSERT(IsUnlinked());
  zx_status_t status;
  std::unique_ptr<Transaction> transaction;

  if ((status = fs_->BeginTransaction(0, 0, &transaction)) != ZX_OK) {
    // In case of error, we still need to release this vnode because it's not possible to retry,
    // and we cannot block destruction. The inode will get cleaned up on next remount.
    fs_->VnodeRelease(this);
    return status;
  }
  // The transaction may go async in journal layer. Hold the reference over this
  // vnode so that we keep the vnode around until the transaction is complete.
  transaction->PinVnode(fbl::RefPtr(this));

  fs_->RemoveUnlinked(transaction.get(), this);
  if ((status = Purge(transaction.get())) != ZX_OK) {
    return status;
  }

  fs_->CommitTransaction(std::move(transaction));
  return ZX_OK;
}

zx_status_t VnodeMinfs::CloseNode() {
  {
    std::lock_guard lock(mutex_);
    if (open_count() != 0) {
      return ZX_OK;
    }
  }

  if (!IsUnlinked()) {
    auto result = FlushCachedWrites();
    if (result.is_error()) {
      FX_LOGS(ERROR) << "Failed(" << result.error_value()
                     << ") to flush pending writes for inode:" << GetIno();
    }
    return result.status_value();
  }

  // This vnode is unlinked and open_count() == 0. We don't need not flush the dirty
  // contents of the vnode to disk.
  DropCachedWrites();
  return RemoveUnlinked();
}

// Internal read. Usable on directories.
zx_status_t VnodeMinfs::ReadInternal(PendingWork* transaction, void* vdata, size_t len, size_t off,
                                     size_t* actual) {
  // clip to EOF
  if (off >= GetSize()) {
    *actual = 0;
    return ZX_OK;
  }
  if (len > (GetSize() - off)) {
    len = GetSize() - off;
  }

  zx_status_t status;
#ifdef __Fuchsia__
  if ((status = InitVmo()) != ZX_OK) {
    return status;
  } else if ((status = vmo_.read(vdata, off, len)) != ZX_OK) {
    return status;
  } else {
    *actual = len;
  }
#else
  uint8_t* data = static_cast<uint8_t*>(vdata);
  uint8_t* start = data;
  uint32_t n = static_cast<uint32_t>(off / fs_->BlockSize());
  size_t adjust = off % fs_->BlockSize();

  while ((len > 0) && (n < kMinfsMaxFileBlock)) {
    size_t xfer;
    if (len > (fs_->BlockSize() - adjust)) {
      xfer = fs_->BlockSize() - adjust;
    } else {
      xfer = len;
    }

    blk_t bno;
    if ((status = BlockGetReadable(n, &bno)) != ZX_OK) {
      return status;
    }
    if (bno != 0) {
      char bdata[fs_->BlockSize()];
      if (fs_->ReadDat(bno, bdata)) {
        FX_LOGS(ERROR) << "Failed to read data block " << bno;
        return ZX_ERR_IO;
      }
      memcpy(data, bdata + adjust, xfer);
    } else {
      // If the block is not allocated, just read zeros
      memset(data, 0, xfer);
    }

    adjust = 0;
    len -= xfer;
    data = data + xfer;
    n++;
  }
  *actual = data - start;
#endif
  return ZX_OK;
}

// Internal write. Usable on directories.
zx_status_t VnodeMinfs::WriteInternal(Transaction* transaction, const uint8_t* data, size_t len,
                                      size_t off, size_t* actual) {
  // We should be called after validating offset and length. Assert if they are invalid.
  auto new_size_or = safemath::CheckAdd(len, off);
  ZX_ASSERT(new_size_or.IsValid() && new_size_or.ValueOrDie() <= kMinfsMaxFileSize);

  if (len == 0) {
    *actual = 0;
    return ZX_OK;
  }
  zx_status_t status;
#ifdef __Fuchsia__
  // TODO(planders): Once we are splitting up write transactions, assert this on host as well.
  ZX_DEBUG_ASSERT(len <= TransactionLimits::kMaxWriteBytes);
  if ((status = InitVmo()) != ZX_OK) {
    return status;
  }

#else
  size_t max_size = off + len;
#endif

  const uint8_t* const start = data;
  uint32_t n = static_cast<uint32_t>(off / fs_->BlockSize());
  size_t adjust = off % fs_->BlockSize();

  while (len > 0) {
    ZX_ASSERT(n < kMinfsMaxFileBlock);
    size_t xfer;
    if (len > (fs_->BlockSize() - adjust)) {
      xfer = fs_->BlockSize() - adjust;
    } else {
      xfer = len;
    }

#ifdef __Fuchsia__
    size_t xfer_off = n * fs_->BlockSize() + adjust;
    if ((xfer_off + xfer) > vmo_size_) {
      size_t new_size = fbl::round_up(xfer_off + xfer, fs_->BlockSize());
      ZX_DEBUG_ASSERT(new_size >= GetSize());  // Overflow.
      if ((status = vmo_.set_size(new_size)) != ZX_OK) {
        break;
      }
      vmo_size_ = new_size;
    }

    // Update this block of the in-memory VMO
    if ((status = vmo_.write(data, xfer_off, xfer)) != ZX_OK) {
      break;
    }

    if (!DirtyCacheEnabled()) {
      // Update this block on-disk
      blk_t bno;
      if ((status = BlockGetWritable(transaction, n, &bno))) {
        break;
      }

      IssueWriteback(transaction, n, bno + fs_->Info().dat_block, 1);
    }
#else   // __Fuchsia__
    blk_t bno;
    if ((status = BlockGetWritable(transaction, n, &bno))) {
      break;
    }
    ZX_DEBUG_ASSERT(bno != 0);
    char wdata[fs_->BlockSize()];
    if (fs_->bc_->Readblk(bno + fs_->Info().dat_block, wdata)) {
      break;
    }
    memcpy(wdata + adjust, data, xfer);
    if (len < fs_->BlockSize() && max_size >= GetSize()) {
      memset(wdata + adjust + xfer, 0, fs_->BlockSize() - (adjust + xfer));
    }
    if (fs_->bc_->Writeblk(bno + fs_->Info().dat_block, wdata)) {
      break;
    }
#endif  // __Fuchsia__

    adjust = 0;
    len -= xfer;
    data = data + xfer;
    n++;
  }

  len = data - start;
  if (len == 0) {
    // If more than zero bytes were requested, but zero bytes were written,
    // return an error explicitly (rather than zero).
    if (off >= kMinfsMaxFileSize) {
      return ZX_ERR_FILE_BIG;
    }

    return ZX_ERR_NO_SPACE;
  }

  if ((off + len) > GetSize()) {
    SetSize(static_cast<uint32_t>(off + len));
  }

  *actual = len;

  ValidateVmoTail(GetSize());
  return ZX_OK;
}

zx_status_t VnodeMinfs::GetAttributes(fs::VnodeAttributes* a) {
  FX_LOGS(DEBUG) << "minfs_getattr() vn=" << this << "(#" << ino_ << ")";
  // This transaction exists because acquiring the block size and block
  // count may be unsafe without locking.
  //
  // TODO(unknown): Improve locking semantics of pending data allocation to make this less
  // confusing.
  Transaction transaction(fs_);
  *a = fs::VnodeAttributes();
  a->mode = DTYPE_TO_VTYPE(MinfsMagicType(inode_.magic)) | V_IRUSR | V_IWUSR | V_IRGRP | V_IROTH;
  a->inode = ino_;
  a->content_size = GetSize();
  a->storage_size = GetBlockCount() * fs_->BlockSize();
  a->link_count = inode_.link_count;
  a->creation_time = inode_.create_time;
  a->modification_time = inode_.modify_time;
  return ZX_OK;
}

zx_status_t VnodeMinfs::SetAttributes(fs::VnodeAttributesUpdate attr) {
  int dirty = 0;
  FX_LOGS(DEBUG) << "minfs_setattr() vn=" << this << "(#" << ino_ << ")";
  if (attr.has_creation_time()) {
    inode_.create_time = attr.take_creation_time();
    dirty = 1;
  }
  if (attr.has_modification_time()) {
    inode_.modify_time = attr.take_modification_time();
    dirty = 1;
  }
  if (attr.any()) {
    // any unhandled field update is unsupported
    return ZX_ERR_INVALID_ARGS;
  }

  // Commit transaction if dirty cache is disabled. Otherwise this will
  // happen later.
  if (dirty && !DirtyCacheEnabled()) {
    // write to disk, but don't overwrite the time
    zx_status_t status;
    std::unique_ptr<Transaction> transaction;
    if ((status = fs_->BeginTransaction(0, 0, &transaction)) != ZX_OK) {
      return status;
    }
    InodeSync(transaction.get(), kMxFsSyncDefault);
    transaction->PinVnode(fbl::RefPtr(this));
    fs_->CommitTransaction(std::move(transaction));
  }
  return ZX_OK;
}

VnodeMinfs::VnodeMinfs(Minfs* fs) : fs_(fs) {}

#ifdef __Fuchsia__
void VnodeMinfs::Notify(std::string_view name, unsigned event) { watcher_.Notify(name, event); }
zx_status_t VnodeMinfs::WatchDir(fs::Vfs* vfs, uint32_t mask, uint32_t options,
                                 zx::channel watcher) {
  return watcher_.WatchDir(vfs, this, mask, options, std::move(watcher));
}

#endif

void VnodeMinfs::Allocate(Minfs* fs, uint32_t type, fbl::RefPtr<VnodeMinfs>* out) {
  if (type == kMinfsTypeDir) {
    *out = fbl::AdoptRef(new Directory(fs));
  } else {
    *out = fbl::AdoptRef(new File(fs));
  }
  memset(&(*out)->inode_, 0, sizeof((*out)->inode_));
  (*out)->inode_.magic = MinfsMagic(type);
  (*out)->inode_.create_time = (*out)->inode_.modify_time = GetTimeUTC();
  if (type == kMinfsTypeDir) {
    (*out)->inode_.link_count = 2;
    // "." and "..".
    (*out)->inode_.dirent_count = 2;
  } else {
    (*out)->inode_.link_count = 1;
  }
}

void VnodeMinfs::Recreate(Minfs* fs, ino_t ino, fbl::RefPtr<VnodeMinfs>* out) {
  Inode inode;
  fs->InodeLoad(ino, &inode);
  if (inode.magic == kMinfsMagicDir) {
    *out = fbl::AdoptRef(new Directory(fs));
  } else {
    *out = fbl::AdoptRef(new File(fs));
  }
  memcpy(&(*out)->inode_, &inode, sizeof(inode));

  (*out)->ino_ = ino;
  (*out)->SetSize((*out)->inode_.size);
}

#ifdef __Fuchsia__

constexpr std::string_view kFsName = "minfs";

zx_status_t VnodeMinfs::QueryFilesystem(fuchsia_io::wire::FilesystemInfo* info) {
  uint32_t reserved_blocks = Vfs()->BlocksReserved();
  Transaction transaction(fs_);
  *info = {};
  info->block_size = fs_->BlockSize();
  info->max_filename_size = kMinfsMaxNameSize;
  info->fs_type = VFS_TYPE_MINFS;
  info->fs_id = fs_->GetFsId();
  info->total_bytes = fs_->Info().block_count * fs_->Info().block_size;
  info->used_bytes = (fs_->Info().alloc_block_count + reserved_blocks) * fs_->Info().block_size;
  info->total_nodes = fs_->Info().inode_count;
  info->used_nodes = fs_->Info().alloc_inode_count;

  fuchsia_hardware_block_volume_VolumeInfo fvm_info;
  if (fs_->FVMQuery(&fvm_info) == ZX_OK) {
    uint64_t free_slices = fvm_info.pslice_total_count - fvm_info.pslice_allocated_count;
    info->free_shared_pool_bytes = fvm_info.slice_size * free_slices;
  }

  static_assert(kFsName.size() + 1 < fuchsia_io::wire::kMaxFsNameBuffer, "Minfs name too long");
  info->name[kFsName.copy(reinterpret_cast<char*>(info->name.data()),
                          fuchsia_io::wire::kMaxFsNameBuffer - 1)] = '\0';
  return ZX_OK;
}

zx_status_t VnodeMinfs::GetDevicePath(size_t buffer_len, char* out_name, size_t* out_len) {
  return fs_->bc_->device()->GetDevicePath(buffer_len, out_name, out_len);
}

void VnodeMinfs::GetMetrics(GetMetricsCompleter::Sync& completer) {
  fuchsia_minfs::wire::Metrics metrics;
  zx_status_t status = fs_->GetMetrics(&metrics);
  completer.Reply(status,
                  status == ZX_OK
                      ? fidl::ObjectView<fuchsia_minfs::wire::Metrics>::FromExternal(&metrics)
                      : nullptr);
}

void VnodeMinfs::ToggleMetrics(bool enable, ToggleMetricsCompleter::Sync& completer) {
  fs_->SetMetrics(enable);
  completer.Reply(ZX_OK);
}

void VnodeMinfs::GetAllocatedRegions(GetAllocatedRegionsCompleter::Sync& completer) {
  static_assert(sizeof(fuchsia_minfs::wire::BlockRegion) == sizeof(BlockRegion));
  static_assert(offsetof(fuchsia_minfs::wire::BlockRegion, offset) ==
                offsetof(BlockRegion, offset));
  static_assert(offsetof(fuchsia_minfs::wire::BlockRegion, length) ==
                offsetof(BlockRegion, length));
  zx::vmo vmo;
  zx_status_t status = ZX_OK;
  fbl::Vector<BlockRegion> buffer = fs_->GetAllocatedRegions();
  uint64_t allocations = buffer.size();
  if (allocations != 0) {
    status = zx::vmo::create(sizeof(BlockRegion) * allocations, 0, &vmo);
    if (status == ZX_OK) {
      status = vmo.write(buffer.data(), 0, sizeof(BlockRegion) * allocations);
    }
  }
  if (status == ZX_OK) {
    completer.Reply(ZX_OK, std::move(vmo), allocations);
  } else {
    completer.Reply(status, zx::vmo(), 0);
  };
}

void VnodeMinfs::GetMountState(GetMountStateCompleter::Sync& completer) {
  MountState state = fs_->GetMountState();
  completer.Reply(ZX_OK, fidl::ObjectView<MountState>::FromExternal(&state));
}

#endif

zx_status_t VnodeMinfs::TruncateInternal(Transaction* transaction, size_t len) {
  // We should be called after validating length. Assert if len is unexpected.
  ZX_ASSERT(len <= kMinfsMaxFileSize);

  zx_status_t status = ZX_OK;
#ifdef __Fuchsia__
  // TODO(smklein): We should only init up to 'len'; no need
  // to read in the portion of a large file we plan on deleting.
  if ((status = InitVmo()) != ZX_OK) {
    FX_LOGS(ERROR) << "Truncate failed to initialize VMO: " << status;
    return ZX_ERR_IO;
  }
#endif

  uint64_t inode_size = GetSize();
  if (len < inode_size) {
    // Truncate should make the file shorter.
    blk_t bno = safemath::checked_cast<blk_t>(inode_size / fs_->BlockSize());

    // Truncate to the nearest block.
    blk_t trunc_bno = static_cast<blk_t>(len / fs_->BlockSize());
    // [start_bno, EOF) blocks should be deleted entirely.
    blk_t start_bno = static_cast<blk_t>((len % fs_->BlockSize() == 0) ? trunc_bno : trunc_bno + 1);

    if ((status = BlocksShrink(transaction, start_bno)) != ZX_OK) {
      return status;
    }

#ifdef __Fuchsia__
    uint64_t decommit_offset = fbl::round_up(len, fs_->BlockSize());
    uint64_t decommit_length = fbl::round_up(inode_size, fs_->BlockSize()) - decommit_offset;
    if (decommit_length > 0) {
      status = vmo_.op_range(ZX_VMO_OP_DECOMMIT, decommit_offset, decommit_length, nullptr, 0);
      if (status != ZX_OK) {
        // TODO(fxbug.dev/35948): This is a known issue; the additional logging here is to help
        // diagnose.
        FX_LOGS(ERROR) << "TruncateInternal: Modifying node length from " << inode_size << " to "
                       << len;
        FX_LOGS(ERROR) << "  Decommit from offset " << decommit_offset << ", length "
                       << decommit_length << ". Status: " << status;
        ZX_ASSERT(status == ZX_OK);
      }
    }
#endif
    // Shrink the size to be block-aligned if we are removing blocks from
    // the end of the vnode.
    if (start_bno * fs_->BlockSize() < inode_size) {
      SetSize(start_bno * fs_->BlockSize());
    }

    // Write zeroes to the rest of the remaining block, if it exists
    if (len < GetSize()) {
      char bdata[fs_->BlockSize()];
      blk_t rel_bno = static_cast<blk_t>(len / fs_->BlockSize());
      bno = 0;
      if ((status = BlockGetReadable(rel_bno, &bno)) != ZX_OK) {
        FX_LOGS(ERROR) << "Truncate failed to get block " << rel_bno << " of file: " << status;
        return ZX_ERR_IO;
      }

      size_t adjust = len % fs_->BlockSize();
#ifdef __Fuchsia__
      bool allocated = (bno != 0);
      if (allocated || HasPendingAllocation(rel_bno)) {
        if ((status = vmo_.read(bdata, len - adjust, adjust)) != ZX_OK) {
          FX_LOGS(ERROR) << "Truncate failed to read last block: " << status;
          return ZX_ERR_IO;
        }
        memset(bdata + adjust, 0, fs_->BlockSize() - adjust);

        if ((status = vmo_.write(bdata, len - adjust, fs_->BlockSize())) != ZX_OK) {
          FX_LOGS(ERROR) << "Truncate failed to write last block: " << status;
          return ZX_ERR_IO;
        }

        if ((status = BlockGetWritable(transaction, rel_bno, &bno)) != ZX_OK) {
          FX_LOGS(ERROR) << "Truncate failed to get block " << rel_bno << " of file: " << status;
          return ZX_ERR_IO;
        }
        IssueWriteback(transaction, rel_bno, bno + fs_->Info().dat_block, 1);
      }
#else   // __Fuchsia__
      if (bno != 0) {
        if (fs_->bc_->Readblk(bno + fs_->Info().dat_block, bdata)) {
          return ZX_ERR_IO;
        }
        memset(bdata + adjust, 0, fs_->BlockSize() - adjust);
        if (fs_->bc_->Writeblk(bno + fs_->Info().dat_block, bdata)) {
          return ZX_ERR_IO;
        }
      }
#endif  // __Fuchsia__
    }
  } else if (len > inode_size) {
    // Truncate should make the file longer, filled with zeroes.
    if (kMinfsMaxFileSize < len) {
      return ZX_ERR_INVALID_ARGS;
    }
#ifdef __Fuchsia__
    uint64_t new_size = fbl::round_up(len, fs_->BlockSize());
    if ((status = vmo_.set_size(new_size)) != ZX_OK) {
      return status;
    }
    vmo_size_ = new_size;
#endif
  } else {
    return ZX_OK;
  }

  // Setting the size does not ensure the on-disk inode is updated. Ensuring
  // writeback occurs is the responsibility of the caller.
  SetSize(static_cast<uint32_t>(len));
  ValidateVmoTail(GetSize());
  return ZX_OK;
}

#ifdef __Fuchsia__
zx_status_t VnodeMinfs::GetNodeInfoForProtocol([[maybe_unused]] fs::VnodeProtocol protocol,
                                               [[maybe_unused]] fs::Rights rights,
                                               fs::VnodeRepresentation* info) {
  if (IsDirectory()) {
    *info = fs::VnodeRepresentation::Directory();
  } else {
    *info = fs::VnodeRepresentation::File();
  }
  return ZX_OK;
}

void VnodeMinfs::Sync(SyncCallback closure) {
  TRACE_DURATION("minfs", "VnodeMinfs::Sync");
  // The transaction may go async in journal layer. Hold the reference over this
  // vnode so that we keep the vnode around until the transaction is complete.
  auto vn = fbl::RefPtr(this);
  fs_->Sync([vn, cb = std::move(closure)](zx_status_t status) mutable {
    // This is called on the journal thread. Operations here must be threadsafe.
    if (status != ZX_OK) {
      cb(status);
      return;
    }
    status = vn->fs_->bc_->Sync();
    cb(status);
  });
  return;
}

zx_status_t VnodeMinfs::AttachRemote(fs::MountChannel h) {
  if (kMinfsRootIno == ino_) {
    return ZX_ERR_ACCESS_DENIED;
  } else if (!IsDirectory() || IsUnlinked()) {
    return ZX_ERR_NOT_DIR;
  } else if (IsRemote()) {
    return ZX_ERR_ALREADY_BOUND;
  }
  SetRemote(std::move(h.client_end()));
  return ZX_OK;
}
#endif

}  // namespace minfs
