// Copyright 2017 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/fdio/vfs.h>
#include <lib/memfs/cpp/vnode.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <zircon/device/vfs.h>

#include <memory>
#include <utility>

#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <fbl/ref_ptr.h>
#include <fbl/string_piece.h>
#include <fs/vfs.h>
#include <fs/vfs_types.h>

#include "dnode.h"

namespace memfs {
namespace {

constexpr const char kFsName[] = "memfs";

}

VnodeDir::VnodeDir(Vfs* vfs) : VnodeMemfs(vfs) {
  link_count_ = 1;  // Implied '.'
}

VnodeDir::~VnodeDir() = default;

fs::VnodeProtocolSet VnodeDir::GetProtocols() const { return fs::VnodeProtocol::kDirectory; }

void VnodeDir::Notify(fbl::StringPiece name, unsigned event) { watcher_.Notify(name, event); }

zx_status_t VnodeDir::WatchDir(fs::Vfs* vfs, uint32_t mask, uint32_t options, zx::channel watcher) {
  return watcher_.WatchDir(vfs, this, mask, options, std::move(watcher));
}

zx_status_t VnodeDir::QueryFilesystem(::llcpp::fuchsia::io::FilesystemInfo* info) {
  static_assert(fbl::constexpr_strlen(kFsName) + 1 < ::llcpp::fuchsia::io::MAX_FS_NAME_BUFFER,
                "Memfs name too long");
  *info = {};
  strlcpy(reinterpret_cast<char*>(info->name.data()), kFsName,
          ::llcpp::fuchsia::io::MAX_FS_NAME_BUFFER);
  info->block_size = kMemfsBlksize;
  info->max_filename_size = kDnodeNameMax;
  info->fs_type = VFS_TYPE_MEMFS;
  info->fs_id = vfs()->GetFsId();
  // There's no sensible value to use for the total_bytes for memfs. Fuchsia overcommits memory,
  // which means you can have a memfs that stores more total bytes than the device has physical
  // memory. You can actually commit more total_bytes than the device has physical memory because
  // of zero-page deduplication.
  info->total_bytes = UINT64_MAX;
  // It's also very difficult to come up with a sensible value for used_bytes because memfs vends
  // writable duplicates of its underlying VMOs to its client. The client can manipulate the VMOs
  // in arbitrarily difficult ways to account for their memory usage.
  info->used_bytes = 0;
  info->total_nodes = UINT64_MAX;
  uint64_t deleted_ino_count = GetDeletedInoCounter();
  uint64_t ino_count = GetInoCounter();
  ZX_DEBUG_ASSERT(ino_count >= deleted_ino_count);
  info->used_nodes = ino_count - deleted_ino_count;
  return ZX_OK;
}

zx_status_t VnodeDir::GetVmo(int flags, zx::vmo* out_vmo, size_t* out_size) {
  return ZX_ERR_ACCESS_DENIED;
}

bool VnodeDir::IsRemote() const { return remoter_.IsRemote(); }
zx::channel VnodeDir::DetachRemote() { return remoter_.DetachRemote(); }
zx_handle_t VnodeDir::GetRemote() const { return remoter_.GetRemote(); }
void VnodeDir::SetRemote(zx::channel remote) { return remoter_.SetRemote(std::move(remote)); }

zx_status_t VnodeDir::Lookup(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name) {
  if (!IsDirectory()) {
    return ZX_ERR_NOT_FOUND;
  }
  Dnode* dn;
  zx_status_t r = dnode_->Lookup(name, &dn);
  ZX_DEBUG_ASSERT(r <= 0);
  if (r == ZX_OK) {
    if (dn == nullptr) {
      // Looking up our own vnode
      *out = fbl::RefPtr<VnodeDir>(this);
    } else {
      // Looking up a different vnode
      *out = dn->AcquireVnode();
    }
  }
  return r;
}

zx_status_t VnodeDir::GetAttributes(fs::VnodeAttributes* attr) {
  *attr = fs::VnodeAttributes();
  attr->inode = ino_;
  attr->mode = V_TYPE_DIR | V_IRUSR;
  attr->content_size = 0;
  attr->storage_size = 0;
  attr->link_count = link_count_;
  attr->creation_time = create_time_;
  attr->modification_time = modify_time_;
  return ZX_OK;
}

zx_status_t VnodeDir::GetNodeInfoForProtocol([[maybe_unused]] fs::VnodeProtocol protocol,
                                             [[maybe_unused]] fs::Rights rights,
                                             fs::VnodeRepresentation* info) {
  *info = fs::VnodeRepresentation::Directory();
  return ZX_OK;
}

zx_status_t VnodeDir::Readdir(fs::vdircookie_t* cookie, void* data, size_t len,
                              size_t* out_actual) {
  fs::DirentFiller df(data, len);
  if (!IsDirectory()) {
    // This WAS a directory, but it has been deleted.
    *out_actual = 0;
    return ZX_OK;
  }
  dnode_->Readdir(&df, cookie);
  *out_actual = df.BytesFilled();
  return ZX_OK;
}

// postcondition: reference taken on vn returned through "out"
zx_status_t VnodeDir::Create(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name, uint32_t mode) {
  zx_status_t status;
  if ((status = CanCreate(name)) != ZX_OK) {
    return status;
  }

  fbl::AllocChecker ac;
  fbl::RefPtr<memfs::VnodeMemfs> vn;
  if (S_ISDIR(mode)) {
    vn = fbl::AdoptRef(new (&ac) memfs::VnodeDir(vfs()));
  } else {
    vn = fbl::AdoptRef(new (&ac) memfs::VnodeFile(vfs()));
  }

  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }

  if ((status = AttachVnode(vn, name, S_ISDIR(mode))) != ZX_OK) {
    return status;
  }
  *out = std::move(vn);
  return status;
}

zx_status_t VnodeDir::Unlink(fbl::StringPiece name, bool must_be_dir) {
  if (!IsDirectory()) {
    // Calling unlink from unlinked, empty directory
    return ZX_ERR_BAD_STATE;
  }
  Dnode* dn;
  zx_status_t r;
  if ((r = dnode_->Lookup(name, &dn)) != ZX_OK) {
    return r;
  } else if (dn == nullptr) {
    // Cannot unlink directory 'foo' using the argument 'foo/.'
    return ZX_ERR_UNAVAILABLE;
  } else if (!dn->IsDirectory() && must_be_dir) {
    // Path ending in "/" was requested, implying that the dnode must be a directory
    return ZX_ERR_NOT_DIR;
  } else if ((r = dn->CanUnlink()) != ZX_OK) {
    return r;
  }

  dn->Detach();
  return ZX_OK;
}

zx_status_t VnodeDir::Rename(fbl::RefPtr<fs::Vnode> _newdir, fbl::StringPiece oldname,
                             fbl::StringPiece newname, bool src_must_be_dir, bool dst_must_be_dir) {
  auto newdir = fbl::RefPtr<VnodeMemfs>::Downcast(std::move(_newdir));

  if (!IsDirectory() || !newdir->IsDirectory())
    return ZX_ERR_BAD_STATE;

  Dnode* olddn;
  zx_status_t r;
  // The source must exist
  if ((r = dnode_->Lookup(oldname, &olddn)) != ZX_OK) {
    return r;
  }
  ZX_DEBUG_ASSERT(olddn != nullptr);

  if (!olddn->IsDirectory() && (src_must_be_dir || dst_must_be_dir)) {
    return ZX_ERR_NOT_DIR;
  } else if ((newdir->ino() == ino_) && (oldname == newname)) {
    // Renaming a file or directory to itself?
    // Shortcut success case
    return ZX_OK;
  }

  // Verify that the destination is not a subdirectory of the source (if
  // both are directories).
  if (olddn->IsSubdirectory(newdir->dnode_)) {
    return ZX_ERR_INVALID_ARGS;
  }

  // The destination may or may not exist
  Dnode* targetdn;
  r = newdir->dnode_->Lookup(newname, &targetdn);
  bool target_exists = (r == ZX_OK);
  if (target_exists) {
    ZX_DEBUG_ASSERT(targetdn != nullptr);
    // The target exists. Validate and unlink it.
    if (olddn == targetdn) {
      // Cannot rename node to itself
      return ZX_ERR_INVALID_ARGS;
    }
    if (olddn->IsDirectory() != targetdn->IsDirectory()) {
      // Cannot rename files to directories (and vice versa)
      return ZX_ERR_INVALID_ARGS;
    } else if ((r = targetdn->CanUnlink()) != ZX_OK) {
      return r;
    }
  } else if (r != ZX_ERR_NOT_FOUND) {
    return r;
  }

  // Allocate the new name for the dnode, either by
  // (1) Stealing it from the previous dnode, if it used the same name, or
  // (2) Allocating a new name, if creating a new name.
  std::unique_ptr<char[]> namebuffer(nullptr);
  if (target_exists) {
    namebuffer = targetdn->TakeName();
    targetdn->Detach();
  } else {
    fbl::AllocChecker ac;
    namebuffer.reset(new (&ac) char[newname.length() + 1]);
    if (!ac.check()) {
      return ZX_ERR_NO_MEMORY;
    }
    memcpy(namebuffer.get(), newname.data(), newname.length());
    namebuffer[newname.length()] = '\0';
  }

  // NOTE:
  //
  // Validation ends here, and modifications begin. Rename should not fail
  // beyond this point.

  std::unique_ptr<Dnode> moved_node = olddn->RemoveFromParent();
  olddn->PutName(std::move(namebuffer), newname.length());
  Dnode::AddChild(newdir->dnode_, std::move(moved_node));
  return ZX_OK;
}

zx_status_t VnodeDir::Link(fbl::StringPiece name, fbl::RefPtr<fs::Vnode> target) {
  auto vn = fbl::RefPtr<VnodeMemfs>::Downcast(std::move(target));

  if (!IsDirectory()) {
    // Empty, unlinked parent
    return ZX_ERR_BAD_STATE;
  }

  if (vn->IsDirectory()) {
    // The target must not be a directory
    return ZX_ERR_NOT_FILE;
  }

  if (dnode_->Lookup(name, nullptr) == ZX_OK) {
    // The destination should not exist
    return ZX_ERR_ALREADY_EXISTS;
  }

  // Make a new dnode for the new name, attach the target vnode to it
  std::unique_ptr<Dnode> targetdn;
  if ((targetdn = Dnode::Create(name, vn)) == nullptr) {
    return ZX_ERR_NO_MEMORY;
  }

  // Attach the new dnode to its parent
  Dnode::AddChild(dnode_, std::move(targetdn));

  return ZX_OK;
}

zx_status_t VnodeDir::CreateFromVmo(fbl::StringPiece name, zx_handle_t vmo, zx_off_t off,
                                    zx_off_t len) {
  zx_status_t status;
  if ((status = CanCreate(name)) != ZX_OK) {
    return status;
  }

  fbl::AllocChecker ac;
  fbl::RefPtr<VnodeMemfs> vn;
  vn = fbl::AdoptRef(new (&ac) VnodeVmo(vfs(), vmo, off, len));
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }
  if ((status = AttachVnode(std::move(vn), name, false)) != ZX_OK) {
    return status;
  }

  return ZX_OK;
}

zx_status_t VnodeDir::CanCreate(fbl::StringPiece name) const {
  if (!IsDirectory()) {
    return ZX_ERR_BAD_STATE;
  }
  zx_status_t status;
  if ((status = dnode_->Lookup(name, nullptr)) == ZX_ERR_NOT_FOUND) {
    return ZX_OK;
  } else if (status == ZX_OK) {
    return ZX_ERR_ALREADY_EXISTS;
  }
  return status;
}

zx_status_t VnodeDir::AttachVnode(fbl::RefPtr<VnodeMemfs> vn, fbl::StringPiece name, bool isdir) {
  // dnode takes a reference to the vnode
  std::unique_ptr<Dnode> dn;
  if ((dn = Dnode::Create(name, vn)) == nullptr) {
    return ZX_ERR_NO_MEMORY;
  }

  // Identify that the vnode is a directory (vn->dnode_ != nullptr) so that
  // addding a child will also increment the parent link_count (after all,
  // directories contain a ".." entry, which is a link to their parent).
  if (isdir) {
    vn->dnode_ = dn.get();
  }

  // parent takes first reference
  Dnode::AddChild(dnode_, std::move(dn));
  return ZX_OK;
}

}  // namespace memfs
