// Copyright 2016 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_AUDIO_AUDIO_CORE_AUDIO_LINK_PACKET_SOURCE_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_AUDIO_LINK_PACKET_SOURCE_H_

#include <fbl/ref_ptr.h>

#include <deque>
#include <memory>
#include <mutex>

#include "src/lib/fxl/synchronization/thread_annotations.h"
#include "src/media/audio/audio_core/audio_link.h"
#include "src/media/audio/audio_core/audio_packet_ref.h"
#include "src/media/audio/audio_core/fwd_decls.h"
#include "src/media/audio/audio_core/pending_flush_token.h"

namespace media::audio {

// TODO(johngro): docs
//
class AudioLinkPacketSource : public AudioLink {
 public:
  static fbl::RefPtr<AudioLinkPacketSource> Create(
      fbl::RefPtr<AudioObject> source, fbl::RefPtr<AudioObject> dest);
  ~AudioLinkPacketSource() override;

  // Accessor for the format info assigned to this link.
  //
  // TODO(johngro): Eliminate this. Format information belongs at the generic
  // AudioLink level. Additionally, all sources should be able to to change or
  // invalidate their format info without needing to destroy and re-create any
  // links. Ideally, they should be able to do so without needing to obtain any
  // locks. A lock-less single writer, single reader, triple-buffer object
  // would be perfect for this (I have one of these lying around from a previous
  // project, I just need to see if I am allowed to use it or not).
  const AudioRendererFormatInfo& format_info() const { return *format_info_; }

  // Common pending queue ops.
  bool pending_queue_empty() const {
    std::lock_guard<std::mutex> locker(pending_mutex_);
    return pending_packet_queue_.empty();
  }

  // PendingQueue operations used by the packet source. Never call these from
  // the destination.
  void PushToPendingQueue(const fbl::RefPtr<AudioPacketRef>& packet);
  void FlushPendingQueue(
      const fbl::RefPtr<PendingFlushToken>& flush_token = nullptr);
  void CopyPendingQueue(const fbl::RefPtr<AudioLinkPacketSource>& other);

  // PendingQueue operations used by the destination. Never call these from the
  // source.
  //
  // When consuming audio, destinations must always pair their calls to
  // LockPendingQueueFront and UnlockPendingQueueFront, passing the pointer to
  // the reference to the front of the queue they obtained in the process (even
  // if the front of the queue was nullptr).
  //
  // Doing so ensures that sources which are attempting to flush the pending
  // queue are forced to wait if the front of the queue is involved in a mixing
  // operation. This, in turn, guarantees that audio packets are always
  // returned to the user in the order which they were queued in without forcing
  // AudioRenderers to wait to queue new data if a mix operation is in progress.
  fbl::RefPtr<AudioPacketRef> LockPendingQueueFront(bool* was_flushed);
  void UnlockPendingQueueFront(bool release_packet);

 private:
  AudioLinkPacketSource(fbl::RefPtr<AudioObject> source,
                        fbl::RefPtr<AudioObject> dest,
                        fbl::RefPtr<AudioRendererFormatInfo> format_info);

  fbl::RefPtr<AudioRendererFormatInfo> format_info_;

  std::mutex flush_mutex_;
  mutable std::mutex pending_mutex_;

  std::deque<fbl::RefPtr<AudioPacketRef>> pending_packet_queue_
      FXL_GUARDED_BY(pending_mutex_);
  std::deque<fbl::RefPtr<AudioPacketRef>> pending_flush_packet_queue_
      FXL_GUARDED_BY(pending_mutex_);
  std::deque<fbl::RefPtr<PendingFlushToken>> pending_flush_token_queue_
      FXL_GUARDED_BY(pending_mutex_);
  bool flushed_ FXL_GUARDED_BY(pending_mutex_) = true;
  bool processing_in_progress_ FXL_GUARDED_BY(pending_mutex_) = false;
};

//
// Utility function used by packet-oriented AudioObjects (e.g. AudioRenderer)
inline AudioLinkPacketSource& AsPacketSource(AudioLink& link) {
  FXL_DCHECK(link.source_type() == AudioLink::SourceType::Packet);
  return static_cast<AudioLinkPacketSource&>(link);
}

}  // namespace media::audio

#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_AUDIO_LINK_PACKET_SOURCE_H_
