// Copyright 2019 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_MEDIA_CODEC_CODECS_CHUNK_INPUT_STREAM_H_
#define SRC_MEDIA_CODEC_CODECS_CHUNK_INPUT_STREAM_H_

#include <lib/fit/defer.h>
#include <lib/media/codec_impl/codec_buffer.h>
#include <lib/media/codec_impl/codec_packet.h>

#include <optional>
#include <vector>

#include "timestamp_extrapolator.h"

// A chunk iterator for a stream of input packets. Provides fixed size input
// blocks from the stream of input packets, buffering the end of input packets
// that don't align with the block size until another packet arrives to complete
// the block.
//
// `ChunkInputStream` will extrapolate timestamps with the provided extrapolator
// if the input packet's timestamp does not align with the block size. See
// `TimestampExtrapolator` for extrapolation semantics.
class ChunkInputStream {
 public:
  struct InputBlock {
    // Pointer to data which is set iff `len > 0`.
    const uint8_t* data = nullptr;
    size_t len = 0;
    // Encoders with delay should take care not to encode padding bytes, which
    // would inject silence midstream.
    size_t non_padding_len = 0;
    // Set on the last invocation of the input block processor for the input
    // stream.
    bool is_end_of_stream = false;
    std::optional<uint64_t> timestamp_ish;
    // A timestamp to apply to delayed output. This is only provided at the
    // end of the stream, when there is no way to associate this with input.
    //
    // Audio encoders often add priming samples to the start of their output.
    // Because of this, the last timestamp may belong to samples stuck inside
    // the encoder at the end of the stream.
    //
    // Correct decoders strip priming samples and translate timestamps forward
    // onto the correct samples.
    std::optional<uint64_t> flush_timestamp_ish;
  };

  enum Status {
    kOk = 0,
    kUserTerminated = 1,
    kExtrapolationFailedWithoutTimebase = 2,
  };

  enum ControlFlow {
    kContinue = 0,
    kTerminate = 1,
  };

  using InputBlockProcessor = fit::function<ControlFlow(const InputBlock input_block)>;

  ChunkInputStream(size_t chunk_size, TimestampExtrapolator&& timestamp_extrapolator,
                   InputBlockProcessor&& input_block_processor);

  // Adds a new input packet to the input stream and executes
  // `input_block_processor` for all the newly available input blocks (which may
  // be none).
  //
  // Pointers in an input block should not be stored. They are valid only for
  // their lifetime as an argument to the `input_block_processor`.
  //
  // If `input_block_processor` returns `kTerminate`, iteration over input
  // blocks will stop. After this early termination, all calls to this instance
  // other than ~ChunkInputStream will fail with an `ASSERT` in debug builds.
  Status ProcessInputPacket(const CodecPacket* input_packet);

  // If there are any buffered input bytes, `Flush` will pad the input block
  // with 0s to complete it and yield an input block with the content.
  //
  // The flushed input block, which may or may not have data, will be sent to
  // `flush_block_processor` if provided or `input_block_processor` otherwise.
  // The flushed block will have `is_end_of_stream` set to `true`.
  Status Flush();

 private:
  struct ScratchBlock {
    std::vector<uint8_t> data;
    size_t len = 0;
    bool full() const { return len == data.size(); }
    bool empty() const { return len == 0; }
    uint8_t* empty_start() {
      ZX_DEBUG_ASSERT(empty_bytes_left() > 0);
      return data.data() + len;
    }
    size_t empty_bytes_left() const {
      ZX_DEBUG_ASSERT(len <= data.size());
      return data.size() - len;
    }
  };

  struct InputPacket {
    const CodecPacket* packet = nullptr;
    size_t offset = 0;
    const uint8_t* data_at_offset() const {
      ZX_DEBUG_ASSERT(bytes_unread() > 0);
      return packet->buffer()->base() + packet->start_offset() + offset;
    }
    size_t bytes_unread() const {
      ZX_DEBUG_ASSERT(packet);
      ZX_DEBUG_ASSERT(offset <= packet->valid_length_bytes());
      return packet->valid_length_bytes() - offset;
    }
  };

  // Appends bytes from the input packet to the scratch block until the block
  // runs out of space or the packet runs out of bytes.
  void AppendToScratchBlock(InputPacket* input_packet);

  // Emits a block to the user's `InputBlockProcessor`.
  Status EmitBlock(const uint8_t* data, const size_t non_padding_len,
                   const bool is_end_of_stream = false);

  std::pair<std::optional<uint64_t>, Status> ExtrapolateTimestamp();

  // Returns total number of bytes seen, which may be more than `stream_index_`,
  // because we might have some bytes in the scratch block.
  size_t BytesSeen() const;

  const size_t chunk_size_ = 0;
  TimestampExtrapolator timestamp_extrapolator_;
  const InputBlockProcessor input_block_processor_ = nullptr;

  // The next output timestamp we will attach when emitting a block.
  std::optional<uint64_t> next_output_timestamp_;

  // Index in the input stream we've emitted so far.
  size_t stream_index_ = 0;
  // Temporary space to hold input bytes unaligned with the chunk_size_ until
  // we get more input bytes to complete the chunk, or flush.
  ScratchBlock scratch_block_;

  // Whether the user early-terminated the stream when processing an input
  // block.
  bool early_terminated_ = false;
};

#endif  // SRC_MEDIA_CODEC_CODECS_CHUNK_INPUT_STREAM_H_
