// Copyright 2022 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 <fuchsia/io/cpp/fidl.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/zx/status.h>

#include <utility>

#include <fbl/unique_fd.h>

#include "gtest/gtest.h"
#include "src/lib/storage/block_client/cpp/remote_block_device.h"
#include "src/storage/fs_test/fs_test_fixture.h"
#include "storage/buffer/owned_vmoid.h"
#include "zircon/errors.h"

namespace fs_test {
namespace {

using DeviceTest = fs_test::FilesystemTest;

void CreateFxFile(const std::string& kFilename) {
  fbl::unique_fd fd(open(kFilename.c_str(), O_CREAT | O_RDWR, 0666));
  ASSERT_TRUE(fd);
  ASSERT_EQ(ftruncate(fd.get(), 1024 * 1024), 0);
}

TEST_P(DeviceTest, TestValidDiskFormat) {
  ASSERT_TRUE(fs().Unmount().is_ok());
  fbl::unique_fd device_fd(open(fs().DevicePath()->c_str(), O_RDWR));
  ASSERT_EQ(fs_management::DetectDiskFormat(device_fd.get()), fs_management::kDiskFormatFxfs);
}

TEST_P(DeviceTest, TestWriteThenRead) {
  const std::string kFilename = GetPath("block_device");
  { CreateFxFile(kFilename); }
  auto endpoints = fidl::CreateEndpoints<fuchsia_io::Node>();
  ASSERT_EQ(endpoints.status_value(), ZX_OK);
  auto [client, server] = *std::move(endpoints);

  // Re-open file as block device
  fdio_cpp::FdioCaller caller(fs().GetRootFd());
  ASSERT_EQ(fidl::WireCall(caller.directory())
                ->Open(fuchsia_io::wire::OpenFlags::kRightReadable |
                           fuchsia_io::wire::OpenFlags::kRightWritable,
                       fuchsia_io::wire::kModeTypeBlockDevice, "block_device", std::move(server))
                .status(),
            ZX_OK);

  std::unique_ptr<block_client::RemoteBlockDevice> device;
  ASSERT_EQ(block_client::RemoteBlockDevice::Create(client.TakeChannel(), &device), ZX_OK);

  zx::vmo vmo;
  storage::OwnedVmoid vmoid;
  const size_t kVmoBlocks = 5;
  fuchsia_hardware_block_BlockInfo info = {};
  ASSERT_EQ(device->BlockGetInfo(&info), ZX_OK);
  ASSERT_EQ(zx::vmo::create(kVmoBlocks * info.block_size, 0, &vmo), ZX_OK);
  ASSERT_NO_FATAL_FAILURE(device->BlockAttachVmo(vmo, &vmoid.GetReference(device.get())));

  const size_t kVmoWriteBlocks = 2;
  const size_t kVmoBlockOffset = 1;
  ASSERT_LE(kVmoBlockOffset + kVmoWriteBlocks, kVmoBlocks);
  char write_buf[kVmoWriteBlocks * info.block_size];
  memset(write_buf, 0xa3, sizeof(write_buf));
  ASSERT_EQ(vmo.write(write_buf, kVmoBlockOffset * info.block_size, sizeof(write_buf)), ZX_OK);

  block_fifo_request_t write_request;
  write_request.opcode = BLOCKIO_WRITE;
  write_request.vmoid = vmoid.get();
  write_request.length = kVmoWriteBlocks;
  write_request.vmo_offset = kVmoBlockOffset;
  write_request.dev_offset = 0;
  EXPECT_EQ(device->FifoTransaction(&write_request, 1), ZX_OK);

  // "Clear" vmo, so any data in the vmo after is solely dependent on the following BLOCKIO_READ
  char zero_buf[kVmoBlocks * info.block_size];
  memset(zero_buf, 0, sizeof(zero_buf));
  ASSERT_EQ(vmo.write(zero_buf, 0, sizeof(zero_buf)), ZX_OK);

  char read_buf[kVmoWriteBlocks * info.block_size];
  memset(read_buf, 0, sizeof(read_buf));
  block_fifo_request_t read_request;
  read_request.opcode = BLOCKIO_READ;
  read_request.vmoid = vmoid.get();
  read_request.length = kVmoWriteBlocks;
  read_request.vmo_offset = kVmoBlockOffset;
  read_request.dev_offset = 0;
  ASSERT_EQ(device->FifoTransaction(&read_request, 1), ZX_OK);
  ASSERT_EQ(vmo.read(read_buf, kVmoBlockOffset * info.block_size, sizeof(read_buf)), ZX_OK);
  EXPECT_EQ(memcmp(write_buf, read_buf, sizeof(write_buf)), 0);
}

// Tests multiple reads and writes in a group
TEST_P(DeviceTest, TestGroupWritesThenReads) {
  const std::string kFilename = GetPath("block_device");
  { CreateFxFile(kFilename); }
  auto endpoints = fidl::CreateEndpoints<fuchsia_io::Node>();
  ASSERT_EQ(endpoints.status_value(), ZX_OK);
  auto [client, server] = *std::move(endpoints);

  fdio_cpp::FdioCaller caller(fs().GetRootFd());
  ASSERT_EQ(fidl::WireCall(caller.directory())
                ->Open(fuchsia_io::wire::OpenFlags::kRightReadable |
                           fuchsia_io::wire::OpenFlags::kRightWritable,
                       fuchsia_io::wire::kModeTypeBlockDevice, "block_device", std::move(server))
                .status(),
            ZX_OK);

  std::unique_ptr<block_client::RemoteBlockDevice> device;
  ASSERT_EQ(block_client::RemoteBlockDevice::Create(client.TakeChannel(), &device), ZX_OK);

  const size_t kVmoBlocks = 6;
  zx::vmo vmo;
  storage::OwnedVmoid vmoid;
  fuchsia_hardware_block_BlockInfo info = {};
  ASSERT_EQ(device->BlockGetInfo(&info), ZX_OK);
  ASSERT_EQ(zx::vmo::create(kVmoBlocks * info.block_size, 0, &vmo), ZX_OK);
  ASSERT_NO_FATAL_FAILURE(device->BlockAttachVmo(vmo, &vmoid.GetReference(device.get())));

  // The first group of writes will send 2 write requests, with a buffer size of kVmoWriteBlocks *
  // block_size This test will write and read from vmo and device with an offset to test that read
  // and writes work with offsets
  const size_t kVmoWriteBlocks = 2;
  const size_t kOffsetBlocks = 1;
  ASSERT_LE(kOffsetBlocks + 2 * kVmoWriteBlocks, kVmoBlocks);

  // Write write_buf1 and write_buf2 to vmo with offset = kOffsetBlocks
  char write_buf1[kVmoWriteBlocks * info.block_size];
  memset(write_buf1, 0xa3, sizeof(write_buf1));
  ASSERT_EQ(vmo.write(write_buf1, kOffsetBlocks * info.block_size, sizeof(write_buf1)), ZX_OK);

  char write_buf2[kVmoWriteBlocks * info.block_size];
  memset(write_buf2, 0xf7, sizeof(write_buf2));
  ASSERT_EQ(vmo.write(write_buf2, (kOffsetBlocks + kVmoWriteBlocks) * info.block_size,
                      sizeof(write_buf2)),
            ZX_OK);

  block_fifo_request_t write_requests[2];
  write_requests[0].opcode = BLOCKIO_WRITE;
  write_requests[0].vmoid = vmoid.get();
  write_requests[0].length = kVmoWriteBlocks;
  write_requests[0].vmo_offset = kOffsetBlocks;
  write_requests[0].dev_offset = 0;

  write_requests[1].opcode = BLOCKIO_WRITE;
  write_requests[1].vmoid = vmoid.get();
  write_requests[1].length = kVmoWriteBlocks;
  write_requests[1].vmo_offset = kOffsetBlocks + kVmoWriteBlocks;
  write_requests[1].dev_offset = kVmoWriteBlocks;
  EXPECT_EQ(device->FifoTransaction(write_requests, std::size(write_requests)), ZX_OK);

  char read_buf[kVmoBlocks * info.block_size];
  memset(read_buf, 0, sizeof(read_buf));
  ASSERT_EQ(vmo.write(read_buf, 0, sizeof(read_buf)), ZX_OK);

  block_fifo_request_t read_requests[2];
  read_requests[0].opcode = BLOCKIO_READ;
  read_requests[0].vmoid = vmoid.get();
  read_requests[0].length = kVmoWriteBlocks;
  read_requests[0].vmo_offset = kOffsetBlocks;
  read_requests[0].dev_offset = 0;

  read_requests[1].opcode = BLOCKIO_READ;
  read_requests[1].vmoid = vmoid.get();
  read_requests[1].length = kVmoWriteBlocks;
  read_requests[1].vmo_offset = kOffsetBlocks + kVmoWriteBlocks;
  read_requests[1].dev_offset = kVmoWriteBlocks;
  ASSERT_EQ(device->FifoTransaction(read_requests, std::size(read_requests)), ZX_OK);
  ASSERT_EQ(vmo.read(read_buf, 0, sizeof(read_buf)), ZX_OK);
  EXPECT_EQ(memcmp(write_buf1, read_buf + (kOffsetBlocks * info.block_size), sizeof(write_buf1)),
            0);
  EXPECT_EQ(memcmp(write_buf2, read_buf + ((kOffsetBlocks + kVmoWriteBlocks) * info.block_size),
                   sizeof(write_buf2)),
            0);
}

TEST_P(DeviceTest, TestWriteThenFlushThenRead) {
  const std::string kFilename = GetPath("block_device");
  { CreateFxFile(kFilename); }
  auto endpoints = fidl::CreateEndpoints<fuchsia_io::Node>();
  ASSERT_EQ(endpoints.status_value(), ZX_OK);
  auto [client, server] = *std::move(endpoints);

  fdio_cpp::FdioCaller caller(fs().GetRootFd());
  ASSERT_EQ(fidl::WireCall(caller.directory())
                ->Open(fuchsia_io::wire::OpenFlags::kRightReadable |
                           fuchsia_io::wire::OpenFlags::kRightWritable,
                       fuchsia_io::wire::kModeTypeBlockDevice, "block_device", std::move(server))
                .status(),
            ZX_OK);

  std::unique_ptr<block_client::RemoteBlockDevice> device;
  ASSERT_EQ(block_client::RemoteBlockDevice::Create(client.TakeChannel(), &device), ZX_OK);

  const size_t kVmoBlocks = 2;
  zx::vmo vmo;
  storage::OwnedVmoid vmoid;
  fuchsia_hardware_block_BlockInfo info = {};
  ASSERT_EQ(device->BlockGetInfo(&info), ZX_OK);
  ASSERT_EQ(zx::vmo::create(kVmoBlocks * info.block_size, 0, &vmo), ZX_OK);
  ASSERT_NO_FATAL_FAILURE(device->BlockAttachVmo(vmo, &vmoid.GetReference(device.get())));

  char write_buf[kVmoBlocks * info.block_size];
  memset(write_buf, 0xa3, sizeof(write_buf));
  ASSERT_EQ(vmo.write(write_buf, 0, sizeof(write_buf)), ZX_OK);

  block_fifo_request_t requests[2];
  requests[0].opcode = BLOCKIO_WRITE;
  requests[0].vmoid = vmoid.get();
  requests[0].length = kVmoBlocks;
  requests[0].vmo_offset = 0;
  requests[0].dev_offset = 0;

  requests[1].opcode = BLOCKIO_FLUSH;
  requests[1].vmoid = vmoid.get();
  requests[1].length = 0;
  requests[1].vmo_offset = 0;
  requests[1].dev_offset = 0;
  EXPECT_EQ(device->FifoTransaction(requests, std::size(requests)), ZX_OK);

  char read_buf[kVmoBlocks * info.block_size];
  memset(read_buf, 0, sizeof(read_buf));
  ASSERT_EQ(vmo.write(read_buf, 0, sizeof(read_buf)), ZX_OK);

  block_fifo_request_t read_request;
  read_request.opcode = BLOCKIO_READ;
  read_request.vmoid = vmoid.get();
  read_request.length = kVmoBlocks;
  read_request.vmo_offset = 0;
  read_request.dev_offset = 0;
  ASSERT_EQ(device->FifoTransaction(&read_request, 1), ZX_OK);
  ASSERT_EQ(vmo.read(read_buf, 0, sizeof(read_buf)), ZX_OK);
  EXPECT_EQ(memcmp(write_buf, read_buf, sizeof(write_buf)), 0);
}

TEST_P(DeviceTest, TestInvalidGroupRequests) {
  const std::string kFilename = GetPath("block_device");
  { CreateFxFile(kFilename); }
  auto endpoints = fidl::CreateEndpoints<fuchsia_io::Node>();
  ASSERT_EQ(endpoints.status_value(), ZX_OK);
  auto [client, server] = *std::move(endpoints);

  fdio_cpp::FdioCaller caller(fs().GetRootFd());
  ASSERT_EQ(fidl::WireCall(caller.directory())
                ->Open(fuchsia_io::wire::OpenFlags::kRightReadable |
                           fuchsia_io::wire::OpenFlags::kRightWritable,
                       fuchsia_io::wire::kModeTypeBlockDevice, "block_device", std::move(server))
                .status(),
            ZX_OK);

  std::unique_ptr<block_client::RemoteBlockDevice> device;
  ASSERT_EQ(block_client::RemoteBlockDevice::Create(client.TakeChannel(), &device), ZX_OK);

  const size_t kVmoBlocks = 5;
  zx::vmo vmo;
  storage::OwnedVmoid vmoid;
  fuchsia_hardware_block_BlockInfo info = {};
  ASSERT_EQ(device->BlockGetInfo(&info), ZX_OK);
  ASSERT_EQ(zx::vmo::create(kVmoBlocks * info.block_size, 0, &vmo), ZX_OK);
  ASSERT_NO_FATAL_FAILURE(device->BlockAttachVmo(vmo, &vmoid.GetReference(device.get())));

  block_fifo_request_t requests[3];
  requests[0].opcode = BLOCKIO_FLUSH;
  requests[0].vmoid = vmoid.get();
  requests[0].length = 0;
  requests[0].vmo_offset = 0;
  requests[0].dev_offset = 0;

  // Not a valid request
  requests[1].opcode = BLOCKIO_CLOSE_VMO;
  requests[1].vmoid = 100;
  requests[1].length = 0;
  requests[1].vmo_offset = 0;
  requests[1].dev_offset = 0;

  requests[2].opcode = BLOCKIO_FLUSH;
  requests[2].vmoid = vmoid.get();
  requests[2].length = 0;
  requests[2].vmo_offset = 0;
  requests[2].dev_offset = 0;
  EXPECT_NE(device->FifoTransaction(requests, std::size(requests)), ZX_OK);
}

INSTANTIATE_TEST_SUITE_P(/*no prefix*/, DeviceTest, testing::ValuesIn(AllTestFilesystems()),
                         testing::PrintToStringParamName());
}  // namespace
}  // namespace fs_test
