// 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);
    }
    // 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;
  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
