// Copyright 2021 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 <lib/fpromise/result.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#include <array>
#include <cstdint>
#include <cstdlib>
#include <filesystem>
#include <iostream>
#include <optional>

#include <fbl/unique_fd.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "src/storage/fvm/fvm_check.h"
#include "src/storage/volume_image/adapter/commands.h"
#include "src/storage/volume_image/adapter/commands/file_client.h"
#include "src/storage/volume_image/fvm/fvm_descriptor.h"
#include "src/storage/volume_image/fvm/fvm_image_extend.h"
#include "src/storage/volume_image/fvm/fvm_sparse_image.h"
#include "src/storage/volume_image/fvm/options.h"
#include "src/storage/volume_image/utils/fd_reader.h"
#include "src/storage/volume_image/utils/fd_test_helper.h"
#include "src/storage/volume_image/utils/fd_writer.h"

namespace storage::volume_image {
namespace {

constexpr std::string_view kFvmSparseImagePath =
    STORAGE_VOLUME_IMAGE_ADAPTER_TEST_IMAGE_PATH "test_fvm_small.sparse.blk";

fpromise::result<TempFile, std::string> CreateFvmBlockImage(
    std::optional<uint64_t> length = std::nullopt) {
  auto image_reader_or = FdReader::Create(kFvmSparseImagePath);
  if (image_reader_or.is_error()) {
    return image_reader_or.take_error_result();
  }
  auto image_reader = std::make_unique<FdReader>(image_reader_or.take_value());

  auto fvm_descriptor_or = FvmSparseReadImage(0, std::move(image_reader));
  if (fvm_descriptor_or.is_error()) {
    return fvm_descriptor_or.take_error_result();
  }
  auto fvm_descriptor = fvm_descriptor_or.take_value();
  if (length.has_value()) {
    FvmOptions options = fvm_descriptor.options();
    options.target_volume_size = length;
    auto tmp = FvmDescriptor::Builder(std::move(fvm_descriptor)).SetOptions(options).Build();
    if (tmp.is_error()) {
      return tmp.take_error_result();
    }
    fvm_descriptor = tmp.take_value();
  }

  auto block_image_or = TempFile::Create();
  if (block_image_or.is_error()) {
    return block_image_or.take_error_result();
  }
  auto block_image_writer_or = FdWriter::Create(block_image_or.value().path());
  if (block_image_writer_or.is_error()) {
    return block_image_writer_or.take_error_result();
  }

  if (length.has_value()) {
    if (truncate(block_image_or.value().path().data(),
                 static_cast<off_t>(fvm_descriptor.options().target_volume_size.value())) != 0) {
      return fpromise::error("Failed to truncate image to final size.");
    }
  }

  fvm_descriptor.WriteBlockImage(block_image_writer_or.value());
  return fpromise::ok(block_image_or.take_value());
}

constexpr uint64_t kTrimmedImagePartitionSize = 200 << 20;

fpromise::result<TempFile, std::string> CreateTrimmedFvmBlockImage() {
  auto image_or = CreateFvmBlockImage(kTrimmedImagePartitionSize);
  if (image_or.is_error()) {
    return image_or.take_error_result();
  }
  auto reader_or = FdReader::Create(image_or.value().path());
  if (reader_or.is_error()) {
    return reader_or.take_error_result();
  }

  auto size_or = FvmImageGetTrimmedSize(reader_or.value());
  if (size_or.is_error()) {
    return size_or.take_error_result();
  }

  if (truncate(image_or.value().path().data(), static_cast<off_t>(size_or.value())) != 0) {
    const auto* err = strerror(errno);
    return fpromise::error("Image truncation failed. More specifically: " + std::string(err) + ".");
  }
  return image_or;
}

void CheckFvm(std::string_view image_path, uint64_t expected_partition_size,
              uint64_t expected_image_size) {
  // FVM is valid.
  zx::result file = OpenFile(std::string(image_path).c_str());
  ASSERT_TRUE(file.is_ok()) << file.status_string();
  fvm::Checker fvm_checker(file.value(), 8 * (1 << 10), true);
  ASSERT_TRUE(fvm_checker.Validate());

  // Check that the partition size is correct.
  auto reader_or = FdReader::Create(image_path);
  ASSERT_TRUE(reader_or.is_ok()) << reader_or.error();

  // Partition size.
  auto partition_size_or = FvmImageGetSize(reader_or.value());
  ASSERT_TRUE(partition_size_or.is_ok()) << partition_size_or.error();
  ASSERT_EQ(partition_size_or.value(), expected_partition_size);

  // Image size.
  struct stat fvm_stat = {};
  ASSERT_EQ(stat(image_path.data(), &fvm_stat), 0);
  ASSERT_EQ(static_cast<uint64_t>(fvm_stat.st_size), expected_image_size);
}

TEST(ExtendCommandTest, UpdatesFvmPartitionSizeAndIsValid) {
  ExtendParams params;

  auto fvm_image_or = CreateFvmBlockImage();
  ASSERT_TRUE(fvm_image_or.is_ok()) << fvm_image_or.error() << " " << kFvmSparseImagePath;
  auto fvm_image = fvm_image_or.take_value();
  params.image_path = fvm_image.path();

  auto reader_or = FdReader::Create(fvm_image.path());
  ASSERT_TRUE(reader_or.is_ok()) << reader_or.error();
  auto image_size_or = FvmImageGetSize(reader_or.value());
  ASSERT_TRUE(image_size_or.is_ok()) << image_size_or.error();

  // Pick a bigger size.
  params.length = 2 * image_size_or.value();

  ASSERT_TRUE(Extend(params).is_ok());
  CheckFvm(params.image_path, params.length.value(), params.length.value());
}

TEST(ExtendCommandTest, TrimPartitionSizeMatchesLengthAndImageSizeIsTrimSize) {
  ExtendParams params;

  auto fvm_image_or = CreateFvmBlockImage();
  ASSERT_TRUE(fvm_image_or.is_ok()) << fvm_image_or.error() << " " << kFvmSparseImagePath;
  auto fvm_image = fvm_image_or.take_value();
  params.image_path = fvm_image.path();
  params.should_trim = true;

  auto reader_or = FdReader::Create(fvm_image.path());
  ASSERT_TRUE(reader_or.is_ok()) << reader_or.error();
  auto image_size_or = FvmImageGetSize(reader_or.value());
  ASSERT_TRUE(image_size_or.is_ok()) << image_size_or.error();

  // Pick a bigger size.
  params.length = 2 * image_size_or.value();

  ASSERT_TRUE(Extend(params).is_ok());
  auto expected_image_size_or = FvmImageGetTrimmedSize(reader_or.value());
  ASSERT_TRUE(expected_image_size_or.is_ok()) << expected_image_size_or.error();
  CheckFvm(params.image_path, params.length.value(), expected_image_size_or.value());
}

TEST(ExtendCommandTest, FitWithSmallerLengthKeepsImageSize) {
  ExtendParams params;

  auto fvm_image_or = CreateTrimmedFvmBlockImage();
  ASSERT_TRUE(fvm_image_or.is_ok()) << fvm_image_or.error() << " " << kFvmSparseImagePath;
  auto fvm_image = fvm_image_or.take_value();
  params.image_path = fvm_image.path();
  params.should_use_max_partition_size = true;

  auto reader_or = FdReader::Create(fvm_image.path());
  ASSERT_TRUE(reader_or.is_ok()) << reader_or.error();
  auto image_size_or = FvmImageGetSize(reader_or.value());
  ASSERT_TRUE(image_size_or.is_ok()) << image_size_or.error();

  // A smaller length should default to to image_size.
  params.length = image_size_or.value() / 2;

  auto extend_or = Extend(params);
  ASSERT_TRUE(extend_or.is_ok()) << extend_or.error();
  auto expected_image_size_or = FvmImageGetSize(reader_or.value());
  ASSERT_TRUE(expected_image_size_or.is_ok()) << expected_image_size_or.error();
  CheckFvm(params.image_path, expected_image_size_or.value(), expected_image_size_or.value());
}

TEST(ExtendCommandTest, FitWithLargerLengthExtendsImage) {
  ExtendParams params;

  auto fvm_image_or = CreateFvmBlockImage();
  ASSERT_TRUE(fvm_image_or.is_ok()) << fvm_image_or.error() << " " << kFvmSparseImagePath;
  auto fvm_image = fvm_image_or.take_value();
  params.image_path = fvm_image.path();
  params.should_use_max_partition_size = true;

  auto reader_or = FdReader::Create(fvm_image.path());
  ASSERT_TRUE(reader_or.is_ok()) << reader_or.error();
  auto image_size_or = FvmImageGetSize(reader_or.value());
  ASSERT_TRUE(image_size_or.is_ok()) << image_size_or.error();

  // A larger length should be honored instead of the image size.
  params.length = 2 * image_size_or.value();

  auto extend_or = Extend(params);
  ASSERT_TRUE(extend_or.is_ok()) << extend_or.error();
  CheckFvm(params.image_path, params.length.value(), params.length.value());
}

TEST(ExtendCommandTest, FitAndTrimWithSmallerLengthKeepsImageSize) {
  ExtendParams params;

  auto fvm_image_or = CreateTrimmedFvmBlockImage();
  ASSERT_TRUE(fvm_image_or.is_ok()) << fvm_image_or.error() << " " << kFvmSparseImagePath;
  auto fvm_image = fvm_image_or.take_value();
  params.image_path = fvm_image.path();
  params.should_use_max_partition_size = true;
  params.should_trim = true;

  auto reader_or = FdReader::Create(fvm_image.path());
  ASSERT_TRUE(reader_or.is_ok()) << reader_or.error();
  auto image_size_or = FvmImageGetSize(reader_or.value());
  ASSERT_TRUE(image_size_or.is_ok()) << image_size_or.error();

  // A smaller length should default to to image_size.
  params.length = image_size_or.value() / 2;

  auto extend_or = Extend(params);
  ASSERT_TRUE(extend_or.is_ok()) << extend_or.error();
  auto expected_partition_size_or = FvmImageGetSize(reader_or.value());
  ASSERT_TRUE(expected_partition_size_or.is_ok()) << expected_partition_size_or.error();
  auto expected_image_size_or = FvmImageGetTrimmedSize(reader_or.value());
  ASSERT_TRUE(expected_image_size_or.is_ok()) << expected_image_size_or.error();
  CheckFvm(params.image_path, expected_partition_size_or.value(), expected_image_size_or.value());
}

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