// Copyright 2016 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 <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <tuple>

#include <fbl/unique_fd.h>

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

namespace fs_test {
namespace {

using TruncateTest = FilesystemTest;

void CheckFileContains(const char* filename, const void* data, ssize_t len) {
  char buf[4096];
  struct stat st;

  ASSERT_EQ(stat(filename, &st), 0);
  ASSERT_EQ(st.st_size, len);
  fbl::unique_fd fd(open(filename, O_RDWR, 0644));
  ASSERT_TRUE(fd);
  ASSERT_EQ(read(fd.get(), buf, len), len);
  ASSERT_EQ(memcmp(buf, data, len), 0);
}

void CheckFileEmpty(const char* filename) {
  struct stat st;
  ASSERT_EQ(stat(filename, &st), 0);
  ASSERT_EQ(st.st_size, 0);
}

// Test that the really simple cases of truncate are operational
TEST_P(TruncateTest, TruncateSmall) {
  const char* str = "Hello, World!\n";
  const std::string filename = GetPath("alpha");

  // Try writing a string to a file
  fbl::unique_fd fd(open(filename.c_str(), O_RDWR | O_CREAT, 0644));
  ASSERT_TRUE(fd);
  ASSERT_EQ(write(fd.get(), str, strlen(str)), static_cast<ssize_t>(strlen(str)));
  ASSERT_NO_FATAL_FAILURE(CheckFileContains(filename.c_str(), str, strlen(str)));

  // Check that opening a file with O_TRUNC makes it empty
  fbl::unique_fd fd2(open(filename.c_str(), O_RDWR | O_TRUNC, 0644));
  ASSERT_TRUE(fd2);
  ASSERT_NO_FATAL_FAILURE(CheckFileEmpty(filename.c_str()));

  // Check that we can still write to a file that has been truncated
  ASSERT_EQ(lseek(fd.get(), 0, SEEK_SET), 0);
  ASSERT_EQ(write(fd.get(), str, strlen(str)), static_cast<ssize_t>(strlen(str)));
  ASSERT_NO_FATAL_FAILURE(CheckFileContains(filename.c_str(), str, strlen(str)));

  // Check that we can truncate the file using the "truncate" function
  ASSERT_EQ(truncate(filename.c_str(), 5), 0);
  ASSERT_NO_FATAL_FAILURE(CheckFileContains(filename.c_str(), str, 5));
  ASSERT_EQ(truncate(filename.c_str(), 0), 0);
  ASSERT_NO_FATAL_FAILURE(CheckFileEmpty(filename.c_str()));

  // Check that truncating an already empty file does not cause problems
  ASSERT_EQ(truncate(filename.c_str(), 0), 0);
  ASSERT_NO_FATAL_FAILURE(CheckFileEmpty(filename.c_str()));

  // Check that we can use truncate to extend a file
  char empty[5] = {0, 0, 0, 0, 0};
  ASSERT_EQ(truncate(filename.c_str(), 5), 0);
  ASSERT_NO_FATAL_FAILURE(CheckFileContains(filename.c_str(), empty, 5));

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

enum class SparseTestType {
  UnlinkThenClose,
  CloseThenUnlink,
};

using ParamType = std::tuple<TestFilesystemOptions, SparseTestType>;

class SparseTruncateTest : public BaseFilesystemTest,
                           public testing::WithParamInterface<ParamType> {
 public:
  SparseTruncateTest() : BaseFilesystemTest(std::get<0>(GetParam())) {}

  SparseTestType test_type() const { return std::get<1>(GetParam()); }
};

// This test catches a particular regression in MinFS truncation, where, if a block is cut in half
// for truncation, it is read, filled with zeroes, and written back out to disk.
//
// This test tries to proke at a variety of offsets of interest.
TEST_P(SparseTruncateTest, PartialBlockSparse) {
  // TODO(smklein): Acquire these constants directly from MinFS's header
  constexpr size_t kBlockSize = 8192;
  constexpr size_t kDirectBlocks = 16;
  constexpr size_t kIndirectBlocks = 31;
  constexpr size_t kDirectPerIndirect = kBlockSize / 4;

  uint8_t buf[kBlockSize];
  memset(buf, 0xAB, sizeof(buf));

  off_t write_offsets[] = {
      kBlockSize * 5,
      kBlockSize * kDirectBlocks,
      kBlockSize * kDirectBlocks + kBlockSize * kDirectPerIndirect * 1,
      kBlockSize * kDirectBlocks + kBlockSize * kDirectPerIndirect * 2,
      kBlockSize * kDirectBlocks + kBlockSize * kDirectPerIndirect * kIndirectBlocks -
          2 * kBlockSize,
      kBlockSize * kDirectBlocks + kBlockSize * kDirectPerIndirect * kIndirectBlocks - kBlockSize,
      kBlockSize * kDirectBlocks + kBlockSize * kDirectPerIndirect * kIndirectBlocks,
      kBlockSize * kDirectBlocks + kBlockSize * kDirectPerIndirect * kIndirectBlocks + kBlockSize,
  };

  for (size_t i = 0; i < std::size(write_offsets); i++) {
    off_t write_off = write_offsets[i];
    fbl::unique_fd fd(open(GetPath("truncate-sparse").c_str(), O_CREAT | O_RDWR));
    ASSERT_TRUE(fd);
    ASSERT_EQ(lseek(fd.get(), write_off, SEEK_SET), write_off);
    ASSERT_EQ(write(fd.get(), buf, sizeof(buf)), static_cast<ssize_t>(sizeof(buf)))
        << "errno=" << errno << ", write_off=" << write_off;
    ASSERT_EQ(ftruncate(fd.get(), write_off + 2 * kBlockSize), 0);
    ASSERT_EQ(ftruncate(fd.get(), write_off + kBlockSize + kBlockSize / 2), 0);
    ASSERT_EQ(ftruncate(fd.get(), write_off + kBlockSize / 2), 0);
    ASSERT_EQ(ftruncate(fd.get(), write_off - kBlockSize / 2), 0);
    if (test_type() == SparseTestType::UnlinkThenClose) {
      ASSERT_EQ(unlink(GetPath("truncate-sparse").c_str()), 0);
      ASSERT_EQ(close(fd.release()), 0);
    } else {
      ASSERT_EQ(close(fd.release()), 0);
      ASSERT_EQ(unlink(GetPath("truncate-sparse").c_str()), 0);
    }
  }
}

TEST_P(TruncateTest, Errno) {
  fbl::unique_fd fd(open(GetPath("truncate_errno").c_str(), O_RDWR | O_CREAT | O_EXCL));
  ASSERT_TRUE(fd);

  ASSERT_EQ(ftruncate(fd.get(), -1), -1);
  ASSERT_EQ(errno, EINVAL);
  errno = 0;
  ASSERT_EQ(ftruncate(fd.get(), 1UL << 60), -1);
  ASSERT_EQ(errno, EINVAL);

  ASSERT_EQ(unlink(GetPath("truncate_errno").c_str()), 0);
  ASSERT_EQ(close(fd.release()), 0);
}

std::string GetParamDescription(const testing::TestParamInfo<ParamType> param) {
  std::stringstream s;
  s << std::get<0>(param.param);
  switch (std::get<1>(param.param)) {
    case SparseTestType::UnlinkThenClose:
      s << "UnlinkThenClose";
      break;
    case SparseTestType::CloseThenUnlink:
      s << "CloseThenUnlink";
      break;
  }
  return s.str();
}

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

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

INSTANTIATE_TEST_SUITE_P(
    /*no prefix*/, LargeTruncateTest,
    testing::Combine(testing::ValuesIn(AllTestFilesystems()),
                     testing::Values(std::make_tuple(1 << 10, 100, LargeTruncateTestType::KeepOpen),
                                     std::make_tuple(1 << 10, 100, LargeTruncateTestType::Reopen),
                                     std::make_tuple(1 << 15, 50, LargeTruncateTestType::KeepOpen),
                                     std::make_tuple(1 << 15, 50, LargeTruncateTestType::Reopen))),
    GetDescriptionForLargeTruncateTestParamType);

}  // namespace
}  // namespace fs_test
