// Copyright 2020 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 "src/storage/fs_test/truncate_fixture.h"

#include <fcntl.h>
#include <sched.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <zircon/syscalls.h>

#include <iostream>
#include <memory>

#include <fbl/alloc_checker.h>
#include <fbl/unique_fd.h>

namespace fs_test {
namespace {

void FillFile(int fd, uint8_t* u8, ssize_t new_len, ssize_t old_len) {
  fbl::AllocChecker ac;
  std::unique_ptr<uint8_t[]> readbuf(new (&ac) uint8_t[new_len]);
  ASSERT_TRUE(ac.check());
  if (new_len > old_len) {  // Expanded the file
    // Verify that the file is unchanged up to old_len
    ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0);
    ASSERT_EQ(read(fd, readbuf.get(), old_len), old_len);
    ASSERT_EQ(memcmp(readbuf.get(), u8, old_len), 0);
    // Verify that the file is filled with zeroes from old_len to new_len
    ASSERT_EQ(lseek(fd, old_len, SEEK_SET), old_len);
    ASSERT_EQ(read(fd, readbuf.get(), new_len - old_len), new_len - old_len);
    for (ssize_t n = 0; n < (new_len - old_len); n++) {
      ASSERT_EQ(readbuf[n], 0) << "old_len=" << old_len << ", new_len=" << new_len << ", n=" << n;
    }
    // Overwrite those zeroes with the contents of u8
    ASSERT_EQ(lseek(fd, old_len, SEEK_SET), old_len);
    auto bytes_to_write = new_len - old_len;
    // We write |bytes_to_write| in a loop because write() may succeed but still return fewer bytes
    // than requested.
    while (bytes_to_write > 0) {
      // We need fsync here because CoW based fs(like minfs) may need more blocks than absolute
      // minimum required as updates/overwrites go to a new block while still retaining old
      // block reservation.
      fsync(fd);
      auto written = write(fd, u8 + old_len, new_len - old_len);
      ASSERT_GT(written, 0);
      bytes_to_write -= written;
      old_len += written;
    }
  } else {  // Shrunk the file (or kept it the same length)
    // Verify that the file is unchanged up to new_len
    ASSERT_EQ(lseek(fd, 0, SEEK_SET), 0);
    ASSERT_EQ(read(fd, readbuf.get(), new_len), new_len);
    ASSERT_EQ(memcmp(readbuf.get(), u8, new_len), 0);
  }
}

void CheckedTruncate(TestFilesystem& fs, bool remount, const char* filename, uint8_t* u8,
                     ssize_t new_len) {
  // Acquire the old size
  struct stat st;
  ASSERT_EQ(stat(filename, &st), 0);
  ssize_t old_len = st.st_size;

  // Truncate the file, verify the size gets updated
  fbl::unique_fd fd(open(filename, O_RDWR, 0644));
  ASSERT_TRUE(fd);
  ASSERT_EQ(ftruncate(fd.get(), new_len), 0);
  ASSERT_EQ(stat(filename, &st), 0);
  ASSERT_EQ(st.st_size, new_len);

  // Close and reopen the file; verify the inode stays updated
  ASSERT_EQ(close(fd.release()), 0);
  fd.reset(open(filename, O_RDWR, 0644));
  ASSERT_TRUE(fd);
  ASSERT_EQ(stat(filename, &st), 0);
  ASSERT_EQ(st.st_size, new_len);

  if (remount) {
    ASSERT_EQ(close(fd.release()), 0);
    EXPECT_EQ(fs.Unmount().status_value(), ZX_OK);
    EXPECT_EQ(fs.Fsck().status_value(), ZX_OK);
    EXPECT_EQ(fs.Mount().status_value(), ZX_OK);
    ASSERT_EQ(stat(filename, &st), 0);
    ASSERT_EQ(st.st_size, new_len);
    fd.reset(open(filename, O_RDWR, 0644));
  }

  ASSERT_NO_FATAL_FAILURE(FillFile(fd.get(), u8, new_len, old_len));
}

void CheckedFtruncate(int fd, uint8_t* u8, ssize_t new_len) {
  // Acquire the old size
  struct stat st;
  ASSERT_EQ(fstat(fd, &st), 0);
  ssize_t old_len = st.st_size;

  // Truncate the file, verify the size gets updated
  ASSERT_EQ(ftruncate(fd, new_len), 0);
  ASSERT_EQ(fstat(fd, &st), 0);
  ASSERT_EQ(st.st_size, new_len);

  ASSERT_NO_FATAL_FAILURE(FillFile(fd, u8, new_len, old_len));
}

// Test that truncate doesn't have issues dealing with larger files
// Repeatedly write to / truncate a file.
TEST_P(LargeTruncateTest, RepeatedlyWritingAndTruncatingLargeFileSucceeds) {
  // Fill a test buffer with data
  fbl::AllocChecker ac;
  std::unique_ptr<uint8_t[]> buf(new (&ac) uint8_t[buffer_size()]);
  ASSERT_TRUE(ac.check());

  unsigned seed = static_cast<unsigned>(zx_ticks_get());
  std::cout << "Truncate test using seed: " << seed << std::endl;
  srand(seed);
  for (unsigned n = 0; n < buffer_size(); n++) {
    buf[n] = static_cast<uint8_t>(rand_r(&seed));
  }

  // Start a file filled with a buffer
  const std::string filename = GetPath("alpha");
  fbl::unique_fd fd(open(filename.c_str(), O_RDWR | O_CREAT, 0644));
  ASSERT_TRUE(fd);
  ASSERT_EQ(write(fd.get(), buf.get(), buffer_size()), static_cast<ssize_t>(buffer_size()));

  if (test_type() != LargeTruncateTestType::KeepOpen) {
    ASSERT_EQ(close(fd.release()), 0);
  }

  // Repeatedly truncate / write to the file
  for (size_t i = 0; i < iterations(); ++i) {
    size_t len = rand_r(&seed) % buffer_size();
    if (test_type() == LargeTruncateTestType::KeepOpen) {
      ASSERT_NO_FATAL_FAILURE(CheckedFtruncate(fd.get(), buf.get(), len));
    } else {
      ASSERT_NO_FATAL_FAILURE(CheckedTruncate(fs(), test_type() == LargeTruncateTestType::Remount,
                                              filename.c_str(), buf.get(), len));
    }
  }
  ASSERT_EQ(unlink(filename.c_str()), 0);
  if (test_type() == LargeTruncateTestType::KeepOpen) {
    ASSERT_EQ(close(fd.release()), 0);
  }
}

}  // namespace

std::string GetDescriptionForLargeTruncateTestParamType(
    const testing::TestParamInfo<LargeTruncateTestParamType>& param) {
  std::stringstream s;
  s << std::get<0>(param.param) << "WithBufferSize"
    << std::to_string(std::get<0>(std::get<1>(param.param))) << "Iterations"
    << std::to_string(std::get<1>(std::get<1>(param.param))) << "Type";
  switch (std::get<2>(std::get<1>(param.param))) {
    case LargeTruncateTestType::KeepOpen:
      s << "KeepOpen";
      break;
    case LargeTruncateTestType::Reopen:
      s << "Reopen";
      break;
    case LargeTruncateTestType::Remount:
      s << "Remount";
      break;
  }
  return s.str();
}

}  // namespace fs_test
