// 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.

#ifndef SRC_STORAGE_BLOBFS_BLOB_DATA_PRODUCER_H_
#define SRC_STORAGE_BLOBFS_BLOB_DATA_PRODUCER_H_

#include <lib/zx/status.h>

#include <memory>

#include <fbl/span.h>

namespace blobfs {

class BlobCompressor;
class SeekableDecompressor;

// BlobDataProducer is an abstact class that is used when writing blobs. It produces data (see the
// Consume method) which is then to be written to the device.
class BlobDataProducer {
 public:
  // The number of bytes remaining for this producer.
  virtual uint64_t GetRemainingBytes() const = 0;

  // Producers must be able to accommodate zero padding up to kBlobfsBlockSize if it would be
  // required i.e. if the last span returned is not a whole block size, it must point to a buffer
  // that can be extended with zero padding (which will be done by the caller).
  virtual zx::status<fbl::Span<const uint8_t>> Consume(uint64_t max) = 0;

  // Subclasses should return true if the next call to Consume would invalidate data returned by
  // previous calls to Consume.
  virtual bool NeedsFlush() const { return false; }
};

// A simple producer that just vends data from a supplied span.
class SimpleBlobDataProducer : public BlobDataProducer {
 public:
  explicit SimpleBlobDataProducer(fbl::Span<const uint8_t> data) : data_(data) {}

  // BlobDataProducer implementation:
  uint64_t GetRemainingBytes() const override;
  zx::status<fbl::Span<const uint8_t>> Consume(uint64_t max) override;

 private:
  fbl::Span<const uint8_t> data_;
};

// Merges two producers together with optional padding between them. If there is padding, we
// require the second producer to be able to accomodate padding at the beginning up to
// kBlobfsBlockSize i.e. the first span it returns must point to a buffer that can be prepended with
// up to kBlobfsBlockSize bytes. Both producers should be able to accommodate padding at the end if
// it would be required.
class MergeBlobDataProducer : public BlobDataProducer {
 public:
  MergeBlobDataProducer(BlobDataProducer& first, BlobDataProducer& second, size_t padding);

  // BlobDataProducer implementation:
  uint64_t GetRemainingBytes() const override;
  zx::status<fbl::Span<const uint8_t>> Consume(uint64_t max) override;
  bool NeedsFlush() const override;

 private:
  BlobDataProducer& first_;
  BlobDataProducer& second_;
  size_t padding_;
};

// A producer that allows us to write uncompressed data by decompressing data.  This is used when we
// discover that it is not profitable to compress a blob.  It decompresses into a temporary buffer.
class DecompressBlobDataProducer : public BlobDataProducer {
 public:
  static zx::status<DecompressBlobDataProducer> Create(BlobCompressor& compressor,
                                                       uint64_t decompressed_size);

  // BlobDataProducer implementation:
  uint64_t GetRemainingBytes() const override;
  zx::status<fbl::Span<const uint8_t>> Consume(uint64_t max) override;
  bool NeedsFlush() const override;

 private:
  DecompressBlobDataProducer(std::unique_ptr<SeekableDecompressor> decompressor,
                             uint64_t decompressed_size, size_t buffer_size,
                             const void* compressed_data_start);

  // Decompress into the temporary buffer.
  zx_status_t Decompress();

  std::unique_ptr<SeekableDecompressor> decompressor_;

  // The total number of decompressed bytes left to decompress.
  uint64_t decompressed_remaining_;

  // A temporary buffer we use to decompress into.
  std::unique_ptr<uint8_t[]> buffer_;

  // The size of the temporary buffer.
  const size_t buffer_size_;

  // Pointer to the first byte of compressed data.
  const uint8_t* compressed_data_start_;

  // The current offset of decompressed bytes.
  uint64_t decompressed_offset_ = 0;

  // The current offset in the temporary buffer indicate what to return on the next call to Consume.
  size_t buffer_offset_ = 0;

  // The number of bytes available in the temporary buffer.
  size_t buffer_avail_ = 0;
};

}  // namespace blobfs

#endif  // SRC_STORAGE_BLOBFS_BLOB_DATA_PRODUCER_H_
