// 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_OUTPUT_SINK_H_
#define SRC_MEDIA_CODEC_CODECS_OUTPUT_SINK_H_

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

#include "src/media/lib/mpsc_queue/mpsc_queue.h"

// A sink for blocks of output data that manages output packets and output
// buffers.
//
// An example use case:
//
//   while (input < input_end) {
//     auto [output_block, status] = output_sink.NextOutputBlock(output_size);
//     if (status != OutputSink::kOk) {
//       // handle error
//     }
//     encoder.EncodeInto(&input, output_block.data);
//   }
//
// This class is expected to be used on two or more threads: a writer thread
// that calls `NextOutputBlock` and `Flush`, and then any other thread(s), which
// can also be the writer thread. See comments on each method for thread safety
// guidance.
class OutputSink {
 public:
  enum UserStatus {
    kSuccess = 0,
    kError = 1,
  };

  using Sender = fit::function<UserStatus(CodecPacket* output_packet)>;

  // Output blocks are slices of the underlying packet and buffer.
  //
  // Output blocks will not overlap with one another, and are vended in order.
  // `buffer` is a reference to the underlying codec buffer that `data` points into.
  struct OutputBlock {
    uint8_t* data;
    size_t len;
    const CodecBuffer* buffer;
  };

  // Output result should have the number of bytes written in `len`.
  struct OutputResult {
    size_t len;
    UserStatus status;
    bool key_frame;
  };

  using Writer = fit::function<OutputResult(OutputBlock)>;

  enum Status {
    kOk = 0,
    kUserTerminatedWait = 1,
    kBuffersTooSmall = 2,
    kUserError = 3,
  };

  // Constructs a new output sink that will use `sender` to emit complete or
  // flushed output packets.
  OutputSink(Sender sender, thrd_t writer_thread);

  // Adds an output packet to vend output blocks with. Packets must be added
  // when they are new and when they are recycled.
  //
  // This call is allowed from any thread at any time.
  void AddOutputPacket(CodecPacket* output_packet);

  // Adds an output buffer to vend output blocks with. Buffers need only be
  // added once.
  //
  // This call is allowed from any thread at any time.
  void AddOutputBuffer(const CodecBuffer* output_buffer);

  // Runs the given function, passing in the next output block of at least
  // `write_size` bytes.
  //
  // The function should return the amount of bytes actually written to the
  // block.
  //
  // OutputBlocks are valid for their lifetime as an argument and should not be
  // stashed.
  //
  // The containing packet will be sent when flushed or when it has no room for
  // the next write.
  //
  // When there are not enough output packets or output buffers to satisfy a
  // request, this call will block until the needed resources are added or a
  // call to `StopAllWaits()` terminates the wait.
  //
  // This should only be called on the writer thread.
  Status NextOutputBlock(size_t write_size, std::optional<uint64_t> timestamp_ish,
                         Writer output_block_writer);

  // Flushes the current output packet even if it isn't full.
  //
  // This should only be called on the writer thread.
  Status Flush();

  // Stops all blocking calls from waiting. They will return a
  // `kUserTerminatedWait` status. This class will continue to
  // return `kUserTerminatedWait` instead of blocking until
  // `Reset` is called.
  //
  // This call is allowed from any thread.
  void StopAllWaits();

  // Resets the stream, re-arming it for waits.
  //
  // If `keep_data` is true, the free buffers and packets will not be discarded.
  //
  // This call is allowed from any thread.
  void Reset(bool keep_data = false);

  // Returns whether any packet data has been queued but not sent
  bool HasPendingPacket();

  // Returns the count of added output buffers
  uint32_t OutputBufferCount();

 private:
  bool CurrentPacketHasRoomFor(size_t write_size);

  Status SendCurrentPacket();

  Status SetNewPacketForWrite(size_t write_size);

  Sender sender_;
  const thrd_t writer_thread_;

  BlockingMpscQueue<CodecPacket*> free_output_packets_;
  BlockingMpscQueue<const CodecBuffer*> free_output_buffers_;

  uint32_t buffer_count_;
  CodecPacket* current_packet_ = nullptr;
};

#endif  // SRC_MEDIA_CODEC_CODECS_OUTPUT_SINK_H_
