// 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/async-loop/cpp/loop.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/limits.h>
#include <lib/vfs/cpp/vmo_file.h>
#include <unistd.h>
#include <zircon/processargs.h>

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include "gtest/gtest.h"

namespace {

void FillBuffer(char* buf, size_t size) {
  for (size_t i = 0; i < size; i++) {
    buf[i] = i % 256;
  }
}

zx::vmo MakeTestVmo() {
  zx::vmo ret;
  EXPECT_EQ(ZX_OK, zx::vmo::create(4096, 0, &ret));

  char buf[4096];
  FillBuffer(buf, 4096);
  EXPECT_EQ(ZX_OK, ret.write(buf, 0, 4096));
  return ret;
}

fuchsia::io::FileSyncPtr OpenAsFile(vfs::internal::Node* node, async_dispatcher_t* dispatcher,
                                    bool writable = false) {
  zx::channel local, remote;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &local, &remote));
  EXPECT_EQ(ZX_OK, node->Serve(fuchsia::io::OPEN_RIGHT_READABLE |
                                   (writable ? fuchsia::io::OPEN_RIGHT_WRITABLE : 0),
                               std::move(remote), dispatcher));
  fuchsia::io::FileSyncPtr ret;
  ret.Bind(std::move(local));
  return ret;
}

std::vector<uint8_t> ReadVmo(const zx::vmo& vmo, size_t offset, size_t length) {
  std::vector<uint8_t> ret;
  ret.resize(length);
  EXPECT_EQ(ZX_OK, vmo.read(ret.data(), offset, length));
  return ret;
}

TEST(VmoFile, ConstructTransferOwnership) {
  vfs::VmoFile file(MakeTestVmo(), 24, 1000);
  std::vector<uint8_t> output;
  EXPECT_EQ(ZX_OK, file.ReadAt(1000, 0, &output));
  EXPECT_EQ(1000u, output.size());
}

TEST(VmoFile, Reading) {
  // Create a VmoFile wrapping 1000 bytes starting at offset 24 of the vmo.
  zx::vmo test_vmo = MakeTestVmo();
  vfs::VmoFile file(zx::unowned_vmo(test_vmo), 24, 1000, vfs::VmoFile::WriteOption::READ_ONLY,
                    vfs::VmoFile::Sharing::NONE);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher());
  ASSERT_TRUE(file_ptr.is_bound());

  // Reading the VMO from offset 24 should match reading the file from offset 0.
  std::vector<uint8_t> result;
  std::vector<uint8_t> vmo_result = ReadVmo(test_vmo, 24, 1000);
  zx_status_t status;
  EXPECT_EQ(ZX_OK, file_ptr->Read(500, &status, &result));
  EXPECT_EQ(ZX_OK, status);
  EXPECT_EQ(ReadVmo(test_vmo, 24, 500), result);
  EXPECT_EQ(ZX_OK, file_ptr->Read(500, &status, &result));
  EXPECT_EQ(ZX_OK, status);
  EXPECT_EQ(ReadVmo(test_vmo, 524, 500), result);
}

TEST(VmoFile, GetAttrReadOnly) {
  // Create a VmoFile wrapping 1000 bytes starting at offset 24 of the vmo.
  zx::vmo test_vmo = MakeTestVmo();
  vfs::VmoFile file(zx::unowned_vmo(test_vmo), 24, 1000, vfs::VmoFile::WriteOption::READ_ONLY,
                    vfs::VmoFile::Sharing::NONE);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher());
  ASSERT_TRUE(file_ptr.is_bound());

  fuchsia::io::NodeAttributes attr;
  zx_status_t status;
  EXPECT_EQ(ZX_OK, file_ptr->GetAttr(&status, &attr));
  EXPECT_EQ(ZX_OK, status);
  EXPECT_EQ(1000u, attr.content_size);
  EXPECT_EQ(1000u, attr.storage_size);
  EXPECT_EQ(fuchsia::io::MODE_TYPE_FILE | fuchsia::io::OPEN_RIGHT_READABLE, attr.mode);
}

TEST(VmoFile, GetAttrWritable) {
  // Create a VmoFile wrapping 1000 bytes starting at offset 24 of the vmo.
  zx::vmo test_vmo = MakeTestVmo();
  vfs::VmoFile file(zx::unowned_vmo(test_vmo), 24, 1000, vfs::VmoFile::WriteOption::WRITABLE,
                    vfs::VmoFile::Sharing::NONE);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher());
  ASSERT_TRUE(file_ptr.is_bound());

  fuchsia::io::NodeAttributes attr;
  zx_status_t status;
  EXPECT_EQ(ZX_OK, file_ptr->GetAttr(&status, &attr));
  EXPECT_EQ(ZX_OK, status);
  EXPECT_EQ(1000u, attr.content_size);
  EXPECT_EQ(1000u, attr.storage_size);
  EXPECT_EQ(fuchsia::io::MODE_TYPE_FILE | fuchsia::io::OPEN_RIGHT_READABLE |
                fuchsia::io::OPEN_RIGHT_WRITABLE,
            attr.mode);
}

TEST(VmoFile, ReadOnlyNoSharing) {
  // Create a VmoFile wrapping 1000 bytes starting at offset 24 of the vmo.
  zx::vmo test_vmo = MakeTestVmo();
  vfs::VmoFile file(zx::unowned_vmo(test_vmo), 24, 1000, vfs::VmoFile::WriteOption::READ_ONLY,
                    vfs::VmoFile::Sharing::NONE);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher());
  ASSERT_TRUE(file_ptr.is_bound());

  // Writes should fail, since the VMO is read-only.
  std::vector<uint8_t> value{'a', 'b', 'c', 'd'};
  zx_status_t status;
  size_t actual;
  EXPECT_EQ(ZX_OK, file_ptr->WriteAt(value, 0, &status, &actual));
  EXPECT_NE(ZX_OK, status);

  // Reading the VMO from offset 24 should match reading the file from offset 0.
  std::vector<uint8_t> result;
  std::vector<uint8_t> vmo_result = ReadVmo(test_vmo, 24, 1000);
  EXPECT_EQ(ZX_OK, file_ptr->ReadAt(1000, 0, &status, &result));
  EXPECT_EQ(vmo_result.size(), result.size());
  EXPECT_EQ(vmo_result, result);

  // The file should appear as a regular file, the fact that a VMO is backing it
  // is hidden.
  fuchsia::io::NodeInfo info;
  EXPECT_EQ(ZX_OK, file_ptr->Describe(&info));
  ASSERT_TRUE(info.is_file());
}

TEST(VmoFile, WritableNoSharing) {
  // Create a VmoFile wrapping 1000 bytes starting at offset 24 of the vmo.
  zx::vmo test_vmo = MakeTestVmo();
  vfs::VmoFile file(zx::unowned_vmo(test_vmo), 24, 1000, vfs::VmoFile::WriteOption::WRITABLE,
                    vfs::VmoFile::Sharing::NONE);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher(), /*writable=*/true);
  ASSERT_TRUE(file_ptr.is_bound());

  // Writes should succeed.
  std::vector<uint8_t> value{'a', 'b', 'c', 'd'};
  zx_status_t status;
  size_t actual;
  EXPECT_EQ(ZX_OK, file_ptr->WriteAt(value, 0, &status, &actual));
  EXPECT_EQ(ZX_OK, status);
  EXPECT_EQ(4u, actual);

  // Reading the VMO from offset 24 should match reading the file from offset 0.
  std::vector<uint8_t> result;
  std::vector<uint8_t> vmo_result = ReadVmo(test_vmo, 24, 1000);
  EXPECT_EQ(ZX_OK, file_ptr->ReadAt(1000, 0, &status, &result));
  EXPECT_EQ(vmo_result.size(), result.size());
  EXPECT_EQ(vmo_result, result);
  EXPECT_EQ('a', result[0]);

  // The file should appear as a regular file, the fact that a VMO is backing it
  // is hidden.
  fuchsia::io::NodeInfo info;
  EXPECT_EQ(ZX_OK, file_ptr->Describe(&info));
  ASSERT_TRUE(info.is_file());
}

TEST(VmoFile, ReadOnlyDuplicate) {
  // Create a VmoFile wrapping 1000 bytes starting at offset 24 of the vmo.
  zx::vmo test_vmo = MakeTestVmo();
  vfs::VmoFile file(zx::unowned_vmo(test_vmo), 24, 1000);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher());
  ASSERT_TRUE(file_ptr.is_bound());

  // Writes should fail, since the VMO is read-only.
  std::vector<uint8_t> value{'a', 'b', 'c', 'd'};
  zx_status_t status;
  size_t actual;
  EXPECT_EQ(ZX_OK, file_ptr->WriteAt(value, 0, &status, &actual));
  EXPECT_NE(ZX_OK, status);

  // Reading the VMO from offset 24 should match reading the file from offset 0.
  std::vector<uint8_t> result;
  std::vector<uint8_t> vmo_result = ReadVmo(test_vmo, 24, 1000);
  EXPECT_EQ(ZX_OK, file_ptr->ReadAt(1000, 0, &status, &result));
  EXPECT_EQ(vmo_result.size(), result.size());
  EXPECT_EQ(vmo_result, result);

  // Describing the VMO duplicates the handle, and we can access the entire VMO.
  fuchsia::io::NodeInfo info;
  EXPECT_EQ(ZX_OK, file_ptr->Describe(&info));
  ASSERT_TRUE(info.is_vmofile());
  ASSERT_EQ(1000u, info.vmofile().length);
  ASSERT_EQ(24u, info.vmofile().offset);
  EXPECT_EQ(ReadVmo(test_vmo, 0, 4096), ReadVmo(info.vmofile().vmo, 0, 4096));

  // Writing should fail on the new VMO.
  EXPECT_NE(ZX_OK, info.vmofile().vmo.write("test", 0, 4));
}

TEST(VmoFile, WritableDuplicate) {
  // Create a VmoFile wrapping 1000 bytes starting at offset 24 of the vmo.
  zx::vmo test_vmo = MakeTestVmo();
  vfs::VmoFile file(zx::unowned_vmo(test_vmo), 24, 1000, vfs::VmoFile::WriteOption::WRITABLE);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher(), /*writable=*/true);
  ASSERT_TRUE(file_ptr.is_bound());

  // Writes should succeed.
  std::vector<uint8_t> value{'a', 'b', 'c', 'd'};
  zx_status_t status;
  size_t actual;
  EXPECT_EQ(ZX_OK, file_ptr->WriteAt(value, 0, &status, &actual));
  EXPECT_EQ(ZX_OK, status);
  EXPECT_EQ(4u, actual);

  // Reading the VMO from offset 24 should match reading the file from offset 0.
  std::vector<uint8_t> result;
  std::vector<uint8_t> vmo_result = ReadVmo(test_vmo, 24, 1000);
  EXPECT_EQ(ZX_OK, file_ptr->ReadAt(1000, 0, &status, &result));
  EXPECT_EQ(vmo_result.size(), result.size());
  EXPECT_EQ(vmo_result, result);
  EXPECT_EQ('a', result[0]);

  // Describing the VMO duplicates the handle, and we can access the entire VMO.
  fuchsia::io::NodeInfo info;
  EXPECT_EQ(ZX_OK, file_ptr->Describe(&info));
  ASSERT_TRUE(info.is_vmofile());
  ASSERT_EQ(1000u, info.vmofile().length);
  ASSERT_EQ(24u, info.vmofile().offset);
  EXPECT_EQ(ReadVmo(test_vmo, 0, 4096), ReadVmo(info.vmofile().vmo, 0, 4096));

  // Writing should succeed on the new VMO.
  EXPECT_EQ(ZX_OK, info.vmofile().vmo.write("test", 0, 4));
  EXPECT_EQ(ReadVmo(test_vmo, 0, 4096), ReadVmo(info.vmofile().vmo, 0, 4096));
}

TEST(VmoFile, ReadOnlyCopyOnWrite) {
  // Create a VmoFile wrapping the VMO.
  zx::vmo test_vmo = MakeTestVmo();
  vfs::VmoFile file(zx::unowned_vmo(test_vmo), 0, 4096, vfs::VmoFile::WriteOption::READ_ONLY,
                    vfs::VmoFile::Sharing::CLONE_COW);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher());
  ASSERT_TRUE(file_ptr.is_bound());

  // Writes should fail, since the VMO is read-only.
  std::vector<uint8_t> value{'a', 'b', 'c', 'd'};
  zx_status_t status;
  size_t actual;
  EXPECT_EQ(ZX_OK, file_ptr->WriteAt(value, 0, &status, &actual));
  EXPECT_NE(ZX_OK, status);

  // Reading the VMO shuld match reading the file.
  std::vector<uint8_t> result;
  std::vector<uint8_t> vmo_result = ReadVmo(test_vmo, 0, 4096);
  EXPECT_EQ(ZX_OK, file_ptr->ReadAt(4096, 0, &status, &result));
  EXPECT_EQ(vmo_result.size(), result.size());
  EXPECT_EQ(vmo_result, result);

  // Describing the VMO clones the handle, and we can access the entire VMO.
  fuchsia::io::NodeInfo info;
  EXPECT_EQ(ZX_OK, file_ptr->Describe(&info));
  ASSERT_TRUE(info.is_vmofile());
  ASSERT_EQ(4096u, info.vmofile().length);
  ASSERT_EQ(0u, info.vmofile().offset);
  EXPECT_EQ(ReadVmo(test_vmo, 0, 4096), ReadVmo(info.vmofile().vmo, 0, 4096));

  // Writing should succeed on the new VMO, due to copy on write.
  EXPECT_EQ(ZX_OK, info.vmofile().vmo.write("test", 0, 4));
  EXPECT_NE(ReadVmo(test_vmo, 0, 4096), ReadVmo(info.vmofile().vmo, 0, 4096));
}

TEST(VmoFile, WritableCopyOnWrite) {
  // Create a VmoFile wrapping the VMO.
  zx::vmo test_vmo = MakeTestVmo();
  vfs::VmoFile file(zx::unowned_vmo(test_vmo), 0, 4096, vfs::VmoFile::WriteOption::WRITABLE,
                    vfs::VmoFile::Sharing::CLONE_COW);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher(), /*writable=*/true);
  ASSERT_TRUE(file_ptr.is_bound());

  // Writes should succeed.
  std::vector<uint8_t> value{'a', 'b', 'c', 'd'};
  zx_status_t status;
  size_t actual;
  EXPECT_EQ(ZX_OK, file_ptr->WriteAt(value, 0, &status, &actual));
  EXPECT_EQ(ZX_OK, status);
  EXPECT_EQ(4u, actual);

  // Reading the VMO should match reading the file.
  std::vector<uint8_t> result;
  std::vector<uint8_t> vmo_result = ReadVmo(test_vmo, 0, 4096);
  EXPECT_EQ(ZX_OK, file_ptr->ReadAt(4096, 0, &status, &result));
  EXPECT_EQ(vmo_result.size(), result.size());
  EXPECT_EQ(vmo_result, result);
  EXPECT_EQ('a', result[0]);

  // Describing the VMO duplicates the handle, and we can access the entire VMO.
  fuchsia::io::NodeInfo info;
  EXPECT_EQ(ZX_OK, file_ptr->Describe(&info));
  ASSERT_TRUE(info.is_vmofile());
  ASSERT_EQ(4096u, info.vmofile().length);
  ASSERT_EQ(0u, info.vmofile().offset);
  EXPECT_EQ(ReadVmo(test_vmo, 0, 4096), ReadVmo(info.vmofile().vmo, 0, 4096));

  // Writing should succeed on the new VMO, due to copy on write.
  EXPECT_EQ(ZX_OK, info.vmofile().vmo.write("test", 0, 4));
  EXPECT_NE(ReadVmo(test_vmo, 0, 4096), ReadVmo(info.vmofile().vmo, 0, 4096));
}

TEST(VmoFile, VmoWithNoRights) {
  // Create a VmoFile wrapping 1000 bytes of the VMO starting at offset 24.
  // The vmo we use has no rights, so reading, writing, and duplication will
  // fail.
  zx::vmo test_vmo = MakeTestVmo();
  zx::vmo bad_vmo;
  ASSERT_EQ(ZX_OK, test_vmo.duplicate(0, &bad_vmo));
  vfs::VmoFile file(std::move(bad_vmo), 24, 1000, vfs::VmoFile::WriteOption::WRITABLE);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher(), /*writable=*/true);
  ASSERT_TRUE(file_ptr.is_bound());

  // Writes should fail.
  std::vector<uint8_t> value{'a', 'b', 'c', 'd'};
  zx_status_t status;
  size_t actual;
  EXPECT_EQ(ZX_OK, file_ptr->WriteAt(value, 0, &status, &actual));
  EXPECT_NE(ZX_OK, status);

  // Reading should fail.
  std::vector<uint8_t> result;
  std::vector<uint8_t> vmo_result = ReadVmo(test_vmo, 24, 1000);
  EXPECT_EQ(ZX_OK, file_ptr->ReadAt(1000, 0, &status, &result));
  EXPECT_NE(ZX_OK, status);

  // Describing the VMO should close the connection.
  fuchsia::io::NodeInfo info;
  EXPECT_EQ(ZX_ERR_PEER_CLOSED, file_ptr->Describe(&info));
}

TEST(VmoFile, UnalignedCopyOnWrite) {
  // Create a VmoFile wrapping 1000 bytes of the VMO starting at offset 24.
  // This offset is not page-aligned, so cloning will fail.
  zx::vmo test_vmo = MakeTestVmo();
  vfs::VmoFile file(zx::unowned_vmo(test_vmo), 24, 1000, vfs::VmoFile::WriteOption::WRITABLE,
                    vfs::VmoFile::Sharing::CLONE_COW);

  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  loop.StartThread("vfs test thread");

  auto file_ptr = OpenAsFile(&file, loop.dispatcher(), /*writable=*/true);
  ASSERT_TRUE(file_ptr.is_bound());

  // Writes should succeed.
  std::vector<uint8_t> value{'a', 'b', 'c', 'd'};
  zx_status_t status;
  size_t actual;
  EXPECT_EQ(ZX_OK, file_ptr->WriteAt(value, 0, &status, &actual));
  EXPECT_EQ(ZX_OK, status);
  EXPECT_EQ(4u, actual);

  // Reading the VMO from offset 24 should match reading the file from offset 0.
  std::vector<uint8_t> result;
  std::vector<uint8_t> vmo_result = ReadVmo(test_vmo, 24, 1000);
  EXPECT_EQ(ZX_OK, file_ptr->ReadAt(1000, 0, &status, &result));
  EXPECT_EQ(vmo_result.size(), result.size());
  EXPECT_EQ(vmo_result, result);
  EXPECT_EQ('a', result[0]);

  // Describing the VMO should close the connection.
  fuchsia::io::NodeInfo info;
  EXPECT_EQ(ZX_ERR_PEER_CLOSED, file_ptr->Describe(&info));
}

}  // namespace
