// 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 <stdio.h>
#include <sys/stat.h>

#include <vector>

#include "blobfs-compression.h"
#include "src/lib/chunked-compression/chunked-compressor.h"
#include "src/lib/chunked-compression/status.h"
#include "src/lib/digest/merkle-tree.h"
#include "src/storage/blobfs/compression/configs/chunked_compression_params.h"
#include "src/storage/blobfs/delivery_blob.h"
#include "src/storage/blobfs/format.h"

namespace blobfs_compress {

// Validate command line |options| used for compressing.
zx_status_t ValidateCliOptions(const CompressionCliOptionStruct& options) {
  if (options.source_file.empty()) {
    return ZX_ERR_INVALID_ARGS;
  }

  // Check source file.
  if (!options.source_file_fd.is_valid()) {
    fprintf(stderr, "Failed to open '%s'.\n", options.source_file.c_str());
    return ZX_ERR_BAD_PATH;
  }
  {
    struct stat info;
    if (fstat(options.source_file_fd.get(), &info) < 0) {
      fprintf(stderr, "stat(%s) failed: %s\n", options.source_file.c_str(), strerror(errno));
      return ZX_ERR_BAD_STATE;
    }
    if (!S_ISREG(info.st_mode)) {
      fprintf(stderr, "%s is not a regular file\n", options.source_file.c_str());
      return ZX_ERR_NOT_FILE;
    }
  }

  // Check compressed output file (can be empty).
  if (!options.compressed_file.empty() && !options.compressed_file_fd.is_valid()) {
    fprintf(stderr, "Failed to open '%s': %s\n", options.compressed_file.c_str(), strerror(errno));
    return ZX_ERR_BAD_PATH;
  }

  return ZX_OK;
}

// Returns 0 if the compression runs successfully; otherwise non-zero values.
// This method reads |src_sz| from |src|, compresses it using the compression
// |params|, and then writes the compressed bytes to |dest_write_buf| and the
// compressed size to |out_compressed_size|. |cli_options| will be used to
// configure what information to include in the output.
//
// |dest_write_buf| can be nullptr if wanting the final compressed size only.
// However, even if |dest_write_buf| is set to nullptr, there will still be
// temporary RAM consumption for storing compressed data due to current internal
// compression API design.
zx_status_t BlobfsCompress(const uint8_t* src, const size_t src_sz, uint8_t* dest_write_buf,
                           size_t* out_compressed_size,
                           chunked_compression::CompressionParams params,
                           const CompressionCliOptionStruct& cli_options) {
  chunked_compression::ChunkedCompressor compressor(params);

  // Using non-compact merkle tree size by default because it's bigger than compact merkle tree.
  const size_t merkle_tree_size =
      digest::CalculateMerkleTreeSize(src_sz, digest::kDefaultNodeSize, false);
  size_t compressed_size;
  size_t output_limit = params.ComputeOutputSizeLimit(src_sz);
  std::vector<uint8_t> output_buffer;

  // The caller does not need the compressed data. However, the compressor
  // still requires a write buffer to store the compressed output.
  if (dest_write_buf == nullptr) {
    output_buffer.resize(fbl::round_up(output_limit + merkle_tree_size, blobfs::kBlobfsBlockSize));
    dest_write_buf = output_buffer.data();
  }

  const auto compression_status =
      compressor.Compress(src, src_sz, dest_write_buf, output_limit, &compressed_size);
  if (compression_status != chunked_compression::kStatusOk) {
    return chunked_compression::ToZxStatus(compression_status);
  }

  // Final size output should be aligned with block size unless disabled explicitly.
  size_t aligned_source_size = src_sz;
  size_t aligned_compressed_size = compressed_size + merkle_tree_size;
  if (!cli_options.disable_size_alignment) {
    aligned_source_size = fbl::round_up(aligned_source_size, blobfs::kBlobfsBlockSize);
    aligned_compressed_size = fbl::round_up(aligned_compressed_size, blobfs::kBlobfsBlockSize);
  }

  double saving_ratio =
      static_cast<double>(aligned_source_size) - static_cast<double>(aligned_compressed_size);
  if (aligned_source_size) {
    saving_ratio /= static_cast<double>(aligned_source_size);
  } else {
    saving_ratio = 0;
  }

  printf("Wrote %lu bytes (%.2f%% space saved).\n", aligned_compressed_size, saving_ratio * 100);

  // By default, filling 0x00 at the end of compressed buffer to match |aligned_compressed_size|.
  *out_compressed_size = aligned_compressed_size;
  return ZX_OK;
}

zx::result<fbl::Array<uint8_t>> GenerateDeliveryBlob(cpp20::span<const uint8_t> data,
                                                     blobfs::DeliveryBlobType type) {
  switch (type) {
    case blobfs::DeliveryBlobType::kType1:
      return blobfs::GenerateDeliveryBlobType1(data, /*compress=*/std::nullopt);
    default:
      return zx::error(ZX_ERR_NOT_SUPPORTED);
  }
}

}  // namespace blobfs_compress
