// 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/lz4_decompressor.h"

#include <array>
#include <cstdint>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <lz4/lz4.h>

#include "src/storage/volume_image/options.h"
#include "src/storage/volume_image/utils/lz4_result.h"

namespace storage::volume_image {
namespace {

constexpr std::array<uint8_t, 4096> kData = {0};

fpromise::result<std::vector<uint8_t>, std::string> GetCompressedData() {
  size_t max_size = LZ4F_compressFrameBound(kData.size(), nullptr);

  std::vector<uint8_t> compressed_data(max_size, 0);

  Lz4Result result = LZ4F_compressFrame(compressed_data.data(), compressed_data.size(),
                                        kData.data(), kData.size(), nullptr);
  if (result.is_error()) {
    return fpromise::error("Failed to compress |kData|. LZ4 Error: " + std::string(result.error()));
  }
  compressed_data.resize(result.byte_count());

  return fpromise::ok(std::move(compressed_data));
}

TEST(Lz4DecompressorTest, CreateWithWrongSchemaIsError) {
  CompressionOptions options;
  options.schema = CompressionSchema::kNone;

  ASSERT_TRUE(Lz4Decompressor::Create(options).is_error());
}

TEST(Lz4DecompressorTest, CreateWithCompressionSchemaLz4IsOk) {
  CompressionOptions options;
  options.schema = CompressionSchema::kLz4;

  ASSERT_TRUE(Lz4Decompressor::Create(options).is_ok());
}

TEST(Lz4DecompressorTest, PrepareAfterConstructionIsOk) {
  CompressionOptions options = {.schema = CompressionSchema::kLz4};
  auto decompressor_or = Lz4Decompressor::Create(options);

  ASSERT_TRUE(decompressor_or.is_ok()) << decompressor_or.error();
  auto decompressor = decompressor_or.take_value();

  EXPECT_TRUE(decompressor.Prepare([](cpp20::span<const uint8_t> buffer) { return fpromise::ok(); })
                  .is_ok());
}

TEST(Lz4DecompressorTest, DecompressWithoutPrepareIsError) {
  CompressionOptions options = {.schema = CompressionSchema::kLz4};
  auto decompressor_or = Lz4Decompressor::Create(options);

  ASSERT_TRUE(decompressor_or.is_ok()) << decompressor_or.error();
  auto decompressor = decompressor_or.take_value();

  EXPECT_TRUE(decompressor.Decompress(cpp20::span<const uint8_t>()).is_error());
}

TEST(Lz4DecompressorTest, FinalizeWithoutPrepareIsError) {
  CompressionOptions options = {.schema = CompressionSchema::kLz4};
  auto decompressor_or = Lz4Decompressor::Create(options);

  ASSERT_TRUE(decompressor_or.is_ok()) << decompressor_or.error();
  auto decompressor = decompressor_or.take_value();

  EXPECT_TRUE(decompressor.Finalize().is_error());
}

TEST(Lz4DecompressorTest, DecompressWithPrepareAndSizeHintIsOk) {
  CompressionOptions options = {.schema = CompressionSchema::kLz4};
  auto decompressor_or = Lz4Decompressor::Create(options);

  ASSERT_TRUE(decompressor_or.is_ok()) << decompressor_or.error();

  auto data_or = GetCompressedData();
  ASSERT_TRUE(data_or.is_ok()) << data_or.error();

  auto decompressor = decompressor_or.take_value();
  ASSERT_TRUE(decompressor
                  .Prepare([](cpp20::span<const uint8_t> buffer) {
                    EXPECT_THAT(buffer, testing::ElementsAreArray(kData));
                    return fpromise::ok();
                  })
                  .is_ok());

  // This should allow us to decompress in one pass.
  decompressor.ProvideSizeHint(kData.size());
  auto decompressor_result = decompressor.Decompress(data_or.value());
  ASSERT_TRUE(decompressor_result.is_ok()) << decompressor_result.error();

  auto [hint, consumed_bytes] = decompressor_result.take_value();
  EXPECT_EQ(hint, static_cast<size_t>(0));
  EXPECT_EQ(consumed_bytes, data_or.value().size());
}

TEST(Lz4DecompressorTest, DecompressOnMultipleStepsIsOk) {
  CompressionOptions options = {.schema = CompressionSchema::kLz4};
  auto decompressor_or = Lz4Decompressor::Create(options);

  ASSERT_TRUE(decompressor_or.is_ok()) << decompressor_or.error();

  auto data_or = GetCompressedData();
  ASSERT_TRUE(data_or.is_ok()) << data_or.error();

  auto decompressor = decompressor_or.take_value();
  size_t total_consumed_bytes = 0;
  size_t decompressed_data_offset = 0;
  ASSERT_TRUE(decompressor
                  .Prepare([&](cpp20::span<const uint8_t> buffer) {
                    EXPECT_THAT(buffer,
                                testing::ElementsAreArray(cpp20::span<const uint8_t>(kData).subspan(
                                    decompressed_data_offset, buffer.size())));
                    decompressed_data_offset += buffer.size();
                    return fpromise::ok();
                  })
                  .is_ok());

  decompressor.ProvideSizeHint(kData.size() / 4);

  bool is_decompression_done = false;
  while (!is_decompression_done) {
    auto decompression_result = decompressor.Decompress(
        cpp20::span<uint8_t>(data_or.value()).subspan(total_consumed_bytes));
    ASSERT_TRUE(decompression_result.is_ok()) << decompression_result.is_error();

    auto [hint, consumed_bytes] = decompression_result.take_value();
    total_consumed_bytes += consumed_bytes;
    is_decompression_done = hint == 0;
  }

  EXPECT_EQ(total_consumed_bytes, data_or.value().size());
}

TEST(Lz4DecompressorTest, FinalizeWithPrepareIsOk) {
  CompressionOptions options = {.schema = CompressionSchema::kLz4};
  auto decompressor_or = Lz4Decompressor::Create(options);

  ASSERT_TRUE(decompressor_or.is_ok()) << decompressor_or.error();
  auto decompressor = decompressor_or.take_value();
  ASSERT_TRUE(decompressor.Prepare([](cpp20::span<const uint8_t> buffer) { return fpromise::ok(); })
                  .is_ok());

  EXPECT_TRUE(decompressor.Finalize().is_ok());
}

TEST(Lz4DecompressorTest, PrepareAfterFinalizeIsOk) {
  CompressionOptions options = {.schema = CompressionSchema::kLz4};
  auto decompressor_or = Lz4Decompressor::Create(options);

  ASSERT_TRUE(decompressor_or.is_ok()) << decompressor_or.error();
  auto decompressor = decompressor_or.take_value();
  ASSERT_TRUE(decompressor.Prepare([](cpp20::span<const uint8_t> buffer) { return fpromise::ok(); })
                  .is_ok());

  EXPECT_TRUE(decompressor.Finalize().is_ok());

  ASSERT_TRUE(decompressor.Prepare([](cpp20::span<const uint8_t> buffer) { return fpromise::ok(); })
                  .is_ok());
}

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