// Copyright 2022 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/lib/chunked-compression/multithreaded-chunked-compressor.h"

#include <lib/stdcompat/span.h>
#include <zircon/errors.h>

#include <thread>
#include <vector>

#include <fbl/array.h>
#include <zxtest/zxtest.h>

#include "src/lib/chunked-compression/chunked-archive.h"
#include "src/lib/chunked-compression/chunked-decompressor.h"
#include "src/lib/chunked-compression/compression-params.h"

namespace chunked_compression {
namespace {

constexpr size_t kThreadCount = 2;
constexpr size_t kChunkSize = 8192;

std::vector<uint8_t> CreateRandomData(size_t size) {
  std::vector<uint8_t> data(size);
  unsigned int seed = zxtest::Runner::GetInstance()->random_seed();
  size_t off = 0;
  size_t rounded_len = fbl::round_down(size, sizeof(int));
  for (off = 0; off < rounded_len; off += sizeof(int)) {
    *reinterpret_cast<int*>(data.data() + off) = rand_r(&seed);
  }
  ZX_ASSERT(off == rounded_len);
  for (; off < size; ++off) {
    data[off] = static_cast<uint8_t>(rand_r(&seed));
  }
  return data;
}

void CheckCompressedData(cpp20::span<const uint8_t> compressed_data,
                         const std::vector<uint8_t>& data) {
  fbl::Array<uint8_t> decompressed_data;
  size_t decompressed_size;
  ASSERT_OK(ChunkedDecompressor::DecompressBytes(compressed_data.data(), compressed_data.size(),
                                                 &decompressed_data, &decompressed_size));
  ASSERT_EQ(decompressed_data.size(), data.size());
  ASSERT_BYTES_EQ(decompressed_data.data(), data.data(), data.size());
}

TEST(MultithreadedChunkedCompressorTest, EmptyInput) {
  CompressionParams params;
  MultithreadedChunkedCompressor compressor(kThreadCount);
  auto result = compressor.Compress(params, cpp20::span<const uint8_t>());
  ASSERT_OK(result.status_value());
  ASSERT_TRUE(result->empty());
}

TEST(MultithreadedChunkedCompressorTest, ChunkAlignedInput) {
  CompressionParams params{
      .chunk_size = kChunkSize,
  };
  auto data = CreateRandomData(kChunkSize * 2);
  MultithreadedChunkedCompressor compressor(kThreadCount);
  auto result = compressor.Compress(params, data);
  ASSERT_OK(result.status_value());
  ASSERT_NO_FATAL_FAILURE(CheckCompressedData(result.value(), data));
}

TEST(MultithreadedChunkedCompressorTest, ChunkUnalignedInput) {
  CompressionParams params{
      .chunk_size = kChunkSize,
  };
  auto data = CreateRandomData(kChunkSize * 2 + 200);
  MultithreadedChunkedCompressor compressor(kThreadCount);
  auto result = compressor.Compress(params, data);
  ASSERT_OK(result.status_value());
  ASSERT_NO_FATAL_FAILURE(CheckCompressedData(result.value(), data));
}

TEST(MultithreadedChunkedCompressorTest, InputTooLargeForChunkSize) {
  CompressionParams params{
      .chunk_size = kChunkSize,
  };
  std::vector<uint8_t> data(kChunkSize * (kChunkArchiveMaxFrames + 1));
  MultithreadedChunkedCompressor compressor(kThreadCount);
  auto result = compressor.Compress(params, data);
  ASSERT_EQ(result.status_value(), ZX_ERR_INVALID_ARGS);
}

TEST(MultithreadedChunkedCompressorTest, CompressMultipleBuffersWithDifferentParamsAtOnce) {
  struct CompressionTask {
    std::vector<uint8_t> data;
    zx::result<fbl::Array<uint8_t>> result;
    CompressionParams params;
  };
  CompressionTask compression_tasks[] = {
      CompressionTask{
          .data = CreateRandomData(kChunkSize * 2 + 5),
          .params = CompressionParams{.chunk_size = kChunkSize},
      },
      CompressionTask{
          .data = CreateRandomData(kChunkSize * 2),
          .params =
              CompressionParams{
                  .chunk_size = kChunkSize,
                  .frame_checksum = true,
              },

      },
      CompressionTask{
          .data = CreateRandomData(kChunkSize * 4),
          .params = CompressionParams{.chunk_size = kChunkSize * 2},
      },
  };
  std::vector<std::thread> threads;
  MultithreadedChunkedCompressor compressor(kThreadCount);
  for (auto& task : compression_tasks) {
    threads.emplace_back(
        [&task, &compressor]() { task.result = compressor.Compress(task.params, task.data); });
  }
  for (auto& thread : threads) {
    thread.join();
  }
  for (const auto& task : compression_tasks) {
    ASSERT_OK(task.result.status_value());
    ASSERT_NO_FATAL_FAILURE(CheckCompressedData(task.result.value(), task.data));
    SeekTable seek_table;
    HeaderReader header_read;
    ASSERT_OK(header_read.Parse(task.result->data(), task.result->size(), task.result->size(),
                                &seek_table));
    // All of the tasks have 2 chunks so the decompressed size of the first chunk should be the
    // chunk size.
    ASSERT_GE(seek_table.Entries().size(), 2);
    ASSERT_EQ(seek_table.Entries()[0].decompressed_size, task.params.chunk_size);
  }
}

}  // namespace
}  // namespace chunked_compression
