// 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/volume_image/utils/fd_reader.h"

#include <fcntl.h>

#include <array>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <limits>

#include <fbl/algorithm.h>
#include <fbl/span.h>
#include <fbl/unique_fd.h>
#include <gtest/gtest.h>

#include "src/storage/volume_image/utils/fd_test_helper.h"

namespace storage::volume_image {
namespace {

TEST(FdReaderTest, CreateFromEmptyPathIsError) { ASSERT_TRUE(FdReader::Create("").is_error()); }

TEST(FdReaderTest, CreateFromPathToInexistentFileIsError) {
  ASSERT_TRUE(
      FdReader::Create("myverylongpaththatdoesnotexistbecauseitsimplydoesnot.nonexistingextension")
          .is_error());
}

TEST(FdReaderTest, CreateFromExistingFileIsOk) {
  auto temp_file_result = TempFile::Create();
  ASSERT_TRUE(temp_file_result.is_ok()) << temp_file_result.error();
  TempFile file = temp_file_result.take_value();

  auto fd_reader_result = FdReader::Create(file.path());
  ASSERT_TRUE(fd_reader_result.is_ok());

  auto fd_reader = fd_reader_result.take_value();
  EXPECT_EQ(fd_reader.name(), file.path());
}

// Wrapper on top of posix, to guarantee to write all contents to the file or fail.
void Write(int fd, fbl::Span<const char> buffer) {
  uint64_t written_bytes = 0;
  while (written_bytes < buffer.size()) {
    auto return_code = write(fd, buffer.data() + written_bytes, buffer.size() - written_bytes);
    ASSERT_GT(return_code, 0);
    written_bytes += return_code;
  }
  fsync(fd);
}

TEST(FdReaderTest, ReadReturnsCorrectContents) {
  constexpr std::string_view kFileContents = "12345678901234567890abcedf12345";

  auto temp_file_result = TempFile::Create();
  ASSERT_TRUE(temp_file_result.is_ok()) << temp_file_result.error();
  TempFile file = temp_file_result.take_value();

  fbl::unique_fd target_fd(open(file.path().data(), O_RDWR | O_APPEND));
  ASSERT_TRUE(target_fd.is_valid());
  ASSERT_NO_FATAL_FAILURE(
      Write(target_fd.get(), fbl::Span(kFileContents.data(), kFileContents.size())));

  auto fd_reader_or_error = FdReader::Create(file.path());
  ASSERT_TRUE(fd_reader_or_error.is_ok()) << fd_reader_or_error.error();
  auto reader = fd_reader_or_error.take_value();

  std::vector<uint8_t> buffer(kFileContents.size(), 0);
  auto read_result = reader.Read(0, buffer);
  ASSERT_TRUE(read_result.is_ok()) << read_result.error();

  EXPECT_TRUE(memcmp(kFileContents.data(), buffer.data(), kFileContents.size()) == 0);
}

TEST(FdReaderTest, ReadReturnsCorrectContentsAtOffset) {
  constexpr std::string_view kFileContents = "12345678901234567890abcedf12345";
  constexpr uint64_t kOffset = 10;
  static_assert(kOffset < kFileContents.size());
  auto temp_file_result = TempFile::Create();
  ASSERT_TRUE(temp_file_result.is_ok()) << temp_file_result.error();
  TempFile file = temp_file_result.take_value();

  fbl::unique_fd target_fd(open(file.path().data(), O_RDWR | O_APPEND));
  ASSERT_TRUE(target_fd.is_valid());
  ASSERT_NO_FATAL_FAILURE(
      Write(target_fd.get(), fbl::Span(kFileContents.data(), kFileContents.size())));

  auto fd_reader_or_error = FdReader::Create(file.path());
  ASSERT_TRUE(fd_reader_or_error.is_ok()) << fd_reader_or_error.error();
  auto reader = fd_reader_or_error.take_value();

  std::vector<uint8_t> buffer(kFileContents.size() - kOffset, 0);
  auto read_result = reader.Read(kOffset, buffer);
  ASSERT_TRUE(read_result.is_ok()) << read_result.error();

  EXPECT_TRUE(
      memcmp(kFileContents.data() + kOffset, buffer.data(), kFileContents.size() - kOffset) == 0);
}

TEST(FdReaderTest, ReadAreIdempotent) {
  constexpr std::string_view kFileContents = "12345678901234567890abcedf12345";

  auto temp_file_result = TempFile::Create();
  ASSERT_TRUE(temp_file_result.is_ok()) << temp_file_result.error();
  TempFile file = temp_file_result.take_value();

  fbl::unique_fd target_fd(open(file.path().data(), O_RDWR | O_APPEND));
  ASSERT_TRUE(target_fd.is_valid());
  ASSERT_NO_FATAL_FAILURE(
      Write(target_fd.get(), fbl::Span(kFileContents.data(), kFileContents.size())));

  auto fd_reader_or_error = FdReader::Create(file.path());
  ASSERT_TRUE(fd_reader_or_error.is_ok()) << fd_reader_or_error.error();
  auto reader = fd_reader_or_error.take_value();

  std::vector<uint8_t> buffer(kFileContents.size(), 0);

  // This checks that, for example a different implementation using read instead of pread, would
  // do appropiate seeks before reading.
  for (uint64_t offset = 0; offset < kFileContents.size() - 1; ++offset) {
    auto read_result = reader.Read(offset, fbl::Span(buffer.data(), buffer.size() - offset));
    ASSERT_TRUE(read_result.is_ok()) << read_result.error();

    EXPECT_TRUE(
        memcmp(kFileContents.data() + offset, buffer.data(), kFileContents.size() - offset) == 0);
  }
}

TEST(FdReaderTest, ReadOutOfBoundsIsError) {
  constexpr std::string_view kFileContents = "12345678901234567890abcedf12345";

  auto temp_file_result = TempFile::Create();
  ASSERT_TRUE(temp_file_result.is_ok()) << temp_file_result.error();
  TempFile file = temp_file_result.take_value();

  fbl::unique_fd target_fd(open(file.path().data(), O_RDWR | O_APPEND));
  ASSERT_TRUE(target_fd.is_valid());
  ASSERT_NO_FATAL_FAILURE(
      Write(target_fd.get(), fbl::Span(kFileContents.data(), kFileContents.size())));

  auto fd_reader_or_error = FdReader::Create(file.path());
  ASSERT_TRUE(fd_reader_or_error.is_ok()) << fd_reader_or_error.error();
  auto reader = fd_reader_or_error.take_value();

  std::vector<uint8_t> buffer(kFileContents.size(), 0);

  // Offset out of bounds.
  EXPECT_TRUE(reader.Read(kFileContents.size(), fbl::Span(buffer.data(), 1)).is_error());

  // Try to read too much.
  EXPECT_TRUE(reader.Read(1, fbl::Span(buffer.data(), buffer.size())).is_error());
}

}  // namespace
}  // namespace storage::volume_image
