// Copyright 2018 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 <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <random>
#include <string_view>

#include <fbl/unique_fd.h>

#include "src/storage/fs_test/fs_test_fixture.h"

namespace fs_test {
namespace {

using RwTest = FilesystemTest;

// Test that zero length read and write operations are valid.
TEST_P(RwTest, ZeroLengthOperations) {
  const std::string filename = GetPath("zero_length_ops");
  fbl::unique_fd fd(open(filename.c_str(), O_RDWR | O_CREAT, 0644));
  ASSERT_TRUE(fd);

  // Zero-length write.
  ASSERT_EQ(write(fd.get(), nullptr, 0), 0);
  ASSERT_EQ(pwrite(fd.get(), nullptr, 0, 0), 0);

  // Zero-length read.
  ASSERT_EQ(read(fd.get(), nullptr, 0), 0);
  ASSERT_EQ(pread(fd.get(), nullptr, 0, 0), 0);

  // Seek pointer unchanged.
  ASSERT_EQ(lseek(fd.get(), 0, SEEK_CUR), 0);

  ASSERT_EQ(close(fd.release()), 0);
  ASSERT_EQ(unlink(filename.c_str()), 0);
}

// Test that zero length write interleaved with non-zero length writes
// works as expected.
TEST_P(RwTest, ZeroLengthOperationWithNonZeroLengthWrites) {
  const std::string filename = GetPath("zero_length_after_large_offset_ops");
  fbl::unique_fd fd(open(filename.c_str(), O_RDWR | O_CREAT, 0644));
  ASSERT_TRUE(fd);

  constexpr size_t kBufferSize = 65374;
  std::unique_ptr<uint8_t[]> buffer(new uint8_t[kBufferSize]());

  memset(buffer.get(), 0, kBufferSize);
  uint64_t kLargeOffset = 50ull * 1024ull * 1024ull;
  uint64_t kOffset = 11ull * 1024ull * 1024ull;

  ASSERT_EQ(pwrite(fd.get(), buffer.get(), kBufferSize, kLargeOffset),
            static_cast<ssize_t>(kBufferSize));
  ASSERT_EQ(pwrite(fd.get(), nullptr, 0, kOffset), 0);
  ASSERT_EQ(pwrite(fd.get(), buffer.get(), kBufferSize, kLargeOffset - 8192),
            static_cast<ssize_t>(kBufferSize));

  ASSERT_EQ(close(fd.release()), 0);
}

// Test that non-zero length read_at and write_at operations are valid.
TEST_P(RwTest, OffsetOperations) {
  srand(0xDEADBEEF);

  constexpr size_t kBufferSize = PAGE_SIZE;
  uint8_t expected[kBufferSize];
  for (size_t i = 0; i < std::size(expected); i++) {
    expected[i] = static_cast<uint8_t>(rand());
  }

  struct TestOption {
    size_t write_start;
    size_t read_start;
    size_t expected_read_length;
  };

  TestOption options[] = {
      {0, 0, kBufferSize},
      {0, 1, kBufferSize - 1},
      {1, 0, kBufferSize},
      {1, 1, kBufferSize},
  };

  for (const auto& opt : options) {
    const std::string filename = GetPath("offset_ops");
    fbl::unique_fd fd(open(filename.c_str(), O_RDWR | O_CREAT, 0644));
    ASSERT_TRUE(fd);

    uint8_t buf[kBufferSize];
    memset(buf, 0, sizeof(buf));

    // 1) Write "kBufferSize" bytes at opt.write_start
    ASSERT_EQ(pwrite(fd.get(), expected, sizeof(expected), opt.write_start),
              static_cast<ssize_t>(sizeof(expected)));

    // 2) Read "kBufferSize" bytes at opt.read_start;
    //    actually read opt.expected_read_length bytes.
    ASSERT_EQ(pread(fd.get(), buf, sizeof(expected), opt.read_start),
              static_cast<ssize_t>(opt.expected_read_length));

    // 3) Verify the contents of the read matched, the seek
    //    pointer is unchanged, and the file size is correct.
    if (opt.write_start <= opt.read_start) {
      size_t read_skip = opt.read_start - opt.write_start;
      ASSERT_EQ(memcmp(buf, expected + read_skip, opt.expected_read_length), 0);
    } else {
      size_t write_skip = opt.write_start - opt.read_start;
      uint8_t zeroes[write_skip];
      memset(zeroes, 0, sizeof(zeroes));
      ASSERT_EQ(memcmp(buf, zeroes, write_skip), 0);
    }
    ASSERT_EQ(lseek(fd.get(), 0, SEEK_CUR), 0);
    struct stat st;
    ASSERT_EQ(fstat(fd.get(), &st), 0);
    ASSERT_EQ(st.st_size, static_cast<ssize_t>(opt.write_start + sizeof(expected)));

    ASSERT_EQ(close(fd.release()), 0);
    ASSERT_EQ(unlink(filename.c_str()), 0);
  }
}

using RwFullDiskTest = FilesystemTest;

TEST_P(RwFullDiskTest, PartialWriteSucceedsForFullDisk) {
  fbl::unique_fd fd(open(GetPath("bigfile").c_str(), O_CREAT | O_RDWR, 0644));
  ASSERT_TRUE(fd);
  constexpr int kBufSize = 131072;
  std::vector<uint64_t> data(kBufSize / sizeof(uint64_t));
  std::random_device random_device;
  std::default_random_engine random(random_device());
  std::uniform_int_distribution<uint64_t> distribution;
  std::generate(data.begin(), data.end(), [&]() { return distribution(random); });
  off_t done = 0;
  for (;;) {
    const off_t offset = done % kBufSize;
    ssize_t len = kBufSize - offset;
    // We should always hit ENOSPC on a power of 2; make sure that we'll always have a short write
    // at the end.
    if (done + len % 2 == 0) {
      --len;
    }
    ssize_t r = write(fd.get(), reinterpret_cast<uint8_t*>(data.data()) + offset, len);
    if (r < 0) {
      EXPECT_EQ(errno, ENOSPC);
      break;
    }
    EXPECT_LE(r, len);
    done += r;
  }
  struct stat stat_buf;
  ASSERT_EQ(fstat(fd.get(), &stat_buf), 0) << errno;
  EXPECT_EQ(stat_buf.st_size, done);
  ASSERT_EQ(lseek(fd.get(), 0, SEEK_SET), 0) << errno;
  std::vector<uint8_t> read_buf(kBufSize);
  off_t verified = 0;
  for (;;) {
    const off_t offset = verified % kBufSize;
    ssize_t len = kBufSize - offset;
    ssize_t r = read(fd.get(), read_buf.data(), len);
    ASSERT_GE(r, 0) << errno;
    if (r == 0) {
      EXPECT_EQ(verified, done);
      break;
    }
    ASSERT_LE(r, len);
    EXPECT_EQ(memcmp(read_buf.data(), reinterpret_cast<uint8_t*>(data.data()) + offset, r), 0);
    verified += r;
  }
}

using RwSparseTest = FilesystemTest;

TEST_P(RwSparseTest, MaxFileSize) {
  constexpr std::string_view kTestData = "hello";
  auto offset = static_cast<off_t>(fs().GetTraits().max_file_size - kTestData.size());
  const std::string foo = GetPath("foo");
  {
    fbl::unique_fd fd(open(foo.c_str(), O_RDWR | O_CREAT, 0644));
    ASSERT_TRUE(fd);
    ASSERT_EQ(pwrite(fd.get(), kTestData.data(), kTestData.size(), offset),
              static_cast<ssize_t>(kTestData.size()));
    ASSERT_EQ(fsync(fd.get()), 0);  // Deliberate sync so that close is likely to unload the vnode.
    ASSERT_EQ(close(fd.release()), 0);
  }
  {
    fbl::unique_fd fd(open(foo.c_str(), O_RDONLY));
    ASSERT_TRUE(fd);
    uint8_t buf[kTestData.size()];
    ASSERT_EQ(pread(fd.get(), buf, kTestData.size(), offset),
              static_cast<ssize_t>(kTestData.size()));
    ASSERT_EQ(memcmp(buf, kTestData.data(), kTestData.size()), 0);
  }
}

INSTANTIATE_TEST_SUITE_P(/*no prefix*/, RwTest, testing::ValuesIn(AllTestFilesystems()),
                         testing::PrintToStringParamName());

INSTANTIATE_TEST_SUITE_P(
    /*no prefix*/, RwFullDiskTest,
    testing::ValuesIn(MapAndFilterAllTestFilesystems(
        [](TestFilesystemOptions options) -> std::optional<TestFilesystemOptions> {
          if (options.filesystem->GetTraits().in_memory) {
            return std::nullopt;
          }
          if (!options.has_min_volume_size) {
            // Run on a smaller ram-disk to keep run-time reasonable.
            options.device_block_count = 8192;
          }
          options.fvm_slice_size = 32768;
          return options;
        })),
    testing::PrintToStringParamName());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RwFullDiskTest);

// These tests will only work on a file system that supports sparse files.
INSTANTIATE_TEST_SUITE_P(
    /*no prefix*/, RwSparseTest,
    testing::ValuesIn(MapAndFilterAllTestFilesystems(
        [](const TestFilesystemOptions& options) -> std::optional<TestFilesystemOptions> {
          if (options.filesystem->GetTraits().supports_sparse_files) {
            return options;
          } else {
            return std::nullopt;
          }
        })),
    testing::PrintToStringParamName());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RwSparseTest);

}  // namespace
}  // namespace fs_test
