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

#ifndef SRC_LIB_CHUNKED_COMPRESSION_STREAMING_CHUNKED_COMPRESSOR_H_
#define SRC_LIB_CHUNKED_COMPRESSION_STREAMING_CHUNKED_COMPRESSOR_H_

#include <memory>
#include <optional>

#include <fbl/array.h>
#include <fbl/function.h>
#include <fbl/macros.h>

#include "chunked-archive.h"
#include "compression-params.h"
#include "status.h"

namespace chunked_compression {

// StreamingChunkedCompressor creates compressed archives by reading a stream of data which has
// a known size ahead of time.
//
// Usage (error checks omitted):
//
//   size_t input_data_sz = InputDataSize();
//
//   StreamingChunkedCompressor compressor;
//   size_t output_limit = compressor.ComputeOutputSizeLimit(input_data_sz);
//
//   fbl::Array<uint8_t> output_buffer(new uint8_t[output_limit], output_limit);
//   compressor.Init(input_data_sz, output_buffer.get(), output_buffer.size());
//
//   uint8_t input_buffer[ReadBufferSize()];
//   size_t bytes_in_buffer;
//   while ((bytes_in_buffer = ReadInput(input_buffer, sizeof(input_buffer)))) {
//     compressor.Update(input_buffer, bytes_in_buffer);
//   }
//
//   size_t compressed_size;
//   compressor.Final(&compressed_size);
class StreamingChunkedCompressor {
 public:
  StreamingChunkedCompressor();
  explicit StreamingChunkedCompressor(CompressionParams params);
  ~StreamingChunkedCompressor();
  StreamingChunkedCompressor(StreamingChunkedCompressor&& o);
  StreamingChunkedCompressor& operator=(StreamingChunkedCompressor&& o);
  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(StreamingChunkedCompressor);

  // Returns the minimum size that a buffer must be to hold the result of compressing |len| bytes.
  size_t ComputeOutputSizeLimit(size_t len) { return params_.ComputeOutputSizeLimit(len); }

  // Initializes the compressor to prepare to recieve |stream_len| bytes of input data.
  //
  // The compressed data will be written to |output|. |output_len| must be at least
  // |ComputeOutputSizeLimit(stream_len)| bytes.
  //
  // If |Init| is invoked while compression is ongoing, the context of the previous compression is
  // reset and the previous output buffer is left in an undefined state.
  Status Init(size_t stream_len, void* output, size_t output_len);

  // Processes exactly |input_len| bytes of input data, read from |input|.
  //
  // If |input_len| bytes would take the streaming compressor past the end of the expected data
  // length (i.e. the |stream_len| parameter to the previous call to |Init|), then an error is
  // returned.
  Status Update(const void* input, size_t input_len);

  // Finalizes the compressed archive, returning its size in |compressed_size_out|.
  //
  // |Final| must be called before the compressed archive is usable, and |Final| must only
  // be called after the entire input has been processed.
  //
  // The compressor is reusable after |Final| is called by invoking |Init| again.
  Status Final(size_t* compressed_size_out);

  // Registers |callback| to be invoked after each frame is complete.
  using ProgressFn =
      fbl::Function<void(size_t bytes_read, size_t bytes_total, size_t bytes_written)>;
  void SetProgressCallback(ProgressFn callback) { progress_callback_ = std::move(callback); }

  const CompressionParams& params() const { return params_; }

 private:
  // Must be called before each new frame is written to, and can only be called when |input_offset_|
  // falls on a frame boundary.
  Status StartFrame();
  // Must be called after each frame is completed.
  Status EndFrame(size_t uncompressed_frame_start, size_t uncompressed_frame_len);
  // Appends |len| bytes to the current frame. |len| must be less than the expected size of the
  // frame.
  // Calls EndFrame if the frame was completed by this data, and then calls StartFrame if there is
  // still more data expected in the input stream.
  Status AppendToFrame(const void* data, size_t len);

  void MoveFrom(StreamingChunkedCompressor&& o);

  uint8_t* compressed_output_ = nullptr;
  size_t compressed_output_len_;
  size_t compressed_output_offset_;

  size_t input_len_;
  size_t input_offset_;

  HeaderWriter header_writer_;

  std::optional<ProgressFn> progress_callback_;

  CompressionParams params_;

  struct CompressionContext;
  std::unique_ptr<CompressionContext> context_;
};

}  // namespace chunked_compression

#endif  // SRC_LIB_CHUNKED_COMPRESSION_STREAMING_CHUNKED_COMPRESSOR_H_
