// Copyright 2019 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 <lib/vfs/cpp/vmo_file.h>

namespace vfs {

VmoFile::VmoFile(zx::unowned_vmo unowned_vmo, size_t offset, size_t length,
                 WriteOption write_option, Sharing vmo_sharing)
    : offset_(offset), length_(length), write_option_(write_option), vmo_sharing_(vmo_sharing) {
  unowned_vmo->duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo_);
}

VmoFile::VmoFile(zx::vmo vmo, size_t offset, size_t length, WriteOption write_option,
                 Sharing vmo_sharing)
    : offset_(offset),
      length_(length),
      write_option_(write_option),
      vmo_sharing_(vmo_sharing),
      vmo_(std::move(vmo)) {}

VmoFile::~VmoFile() = default;

zx::vmo VmoFile::GetVmoForDescribe() {
  zx::vmo result_vmo;
  switch (vmo_sharing_) {
    case Sharing::NONE:
      break;
    case Sharing::DUPLICATE:
      // TODO(fxbug.dev/45287): As part of fxbug.dev/85334 it was discovered that Describe leaks
      // writable handles even if the connection lacks OPEN_RIGHT_WRITABLE. If duplicate handles
      // to the underlying VMO require specific rights, they should be obtained via GetBuffer(),
      // or we need to allow the VmoFile node itself query the connection rights (since these are
      // currently not available when handling the Describe call).
      //
      // If an exact/duplicate handle includes ZX_RIGHT_WRITE, we need to either track possible size
      // changes to the backing VMO, provide a writable child slice, or explicitly set the
      // content size and ensure the duplicate handle lacks ZX_RIGHT_SET_PROPERTY.
      vmo_.duplicate(ZX_RIGHTS_BASIC | ZX_RIGHT_READ | ZX_RIGHT_MAP | ZX_RIGHT_GET_PROPERTY,
                     &result_vmo);
      break;
    case Sharing::CLONE_COW:
      vmo_.create_child(ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE, offset_, length_, &result_vmo);
      break;
  }
  return result_vmo;
}

void VmoFile::Describe(fuchsia::io::NodeInfo* out_info) {
  zx::vmo client_vmo = GetVmoForDescribe();
  switch (vmo_sharing_) {
    case Sharing::NONE:
      out_info->set_file(fuchsia::io::FileObject());
      break;
    case Sharing::DUPLICATE:
    case Sharing::CLONE_COW:
      if (!client_vmo.is_valid()) {
        return;
      }
      out_info->vmofile() =
          fuchsia::io::Vmofile{.vmo = std::move(client_vmo), .offset = offset_, .length = length_};
      break;
  }
}

void VmoFile::Describe2(fuchsia::io::ConnectionInfo* out_info) {
  zx::vmo client_vmo = GetVmoForDescribe();
  switch (vmo_sharing_) {
    case Sharing::NONE:
      out_info->set_representation(fuchsia::io::Representation::WithFile(fuchsia::io::FileInfo()));
      break;
    case Sharing::DUPLICATE:
    case Sharing::CLONE_COW:
      if (!client_vmo.is_valid()) {
        return;
      }
      fuchsia::io::MemoryInfo mem_info;
      mem_info.set_buffer(
          fuchsia::mem::Range{.vmo = std::move(client_vmo), .offset = offset_, .size = length_});
      out_info->set_representation(fuchsia::io::Representation::WithMemory(std::move(mem_info)));
      break;
  }
}

zx_status_t VmoFile::ReadAt(uint64_t length, uint64_t offset, std::vector<uint8_t>* out_data) {
  if (length == 0u || offset >= length_) {
    return ZX_OK;
  }

  size_t remaining_length = length_ - offset;
  if (length > remaining_length) {
    length = remaining_length;
  }

  out_data->resize(length);
  return vmo_.read(out_data->data(), offset_ + offset, length);
}

zx_status_t VmoFile::WriteAt(std::vector<uint8_t> data, uint64_t offset, uint64_t* out_actual) {
  if (write_option_ != WriteOption::WRITABLE) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  size_t length = data.size();
  if (length == 0u) {
    *out_actual = 0u;
    return ZX_OK;
  }
  if (offset >= length_) {
    return ZX_ERR_NO_SPACE;
  }

  size_t remaining_length = length_ - offset;
  if (length > remaining_length) {
    length = remaining_length;
  }
  zx_status_t status = vmo_.write(data.data(), offset_ + offset, length);
  if (status == ZX_OK) {
    *out_actual = length;
  }
  return status;
}

zx_status_t VmoFile::Truncate(uint64_t length) { return ZX_ERR_NOT_SUPPORTED; }

size_t VmoFile::GetCapacity() { return length_; }

size_t VmoFile::GetLength() { return length_; }

zx_status_t VmoFile::GetAttr(fuchsia::io::NodeAttributes* out_attributes) const {
  out_attributes->mode =
      fuchsia::io::MODE_TYPE_FILE | fuchsia::io::OPEN_RIGHT_READABLE |
      (write_option_ == WriteOption::WRITABLE ? fuchsia::io::OPEN_RIGHT_WRITABLE : 0);
  out_attributes->id = fuchsia::io::INO_UNKNOWN;
  out_attributes->content_size = length_;
  out_attributes->storage_size = length_;
  out_attributes->link_count = 1;
  out_attributes->creation_time = 0;
  out_attributes->modification_time = 0;
  return ZX_OK;
}

NodeKind::Type VmoFile::GetKind() const {
  return File::GetKind() | NodeKind::kVmo | NodeKind::kReadable |
         (write_option_ == WriteOption::WRITABLE ? NodeKind::kWritable : 0);
}

}  // namespace vfs
