// 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 GARNET_DRIVERS_AUDIO_VIRTUAL_AUDIO_VIRTUAL_AUDIO_STREAM_H_
#define GARNET_DRIVERS_AUDIO_VIRTUAL_AUDIO_VIRTUAL_AUDIO_STREAM_H_

#include <audio-proto/audio-proto.h>
#include <dispatcher-pool/dispatcher-timer.h>
#include <dispatcher-pool/dispatcher-wakeup-event.h>
#include <fbl/ref_ptr.h>
#include <fuchsia/virtualaudio/cpp/fidl.h>
#include <lib/fzl/vmo-mapper.h>
#include <lib/simple-audio-stream/simple-audio-stream.h>
#include <deque>

namespace virtual_audio {

class VirtualAudioDeviceImpl;

class VirtualAudioStream : public ::audio::SimpleAudioStream {
 public:
  void EnqueuePlugChange(bool plugged) __TA_EXCLUDES(wakeup_queue_lock_);
  void EnqueueGainRequest(
      fuchsia::virtualaudio::Device::GetGainCallback gain_callback)
      __TA_EXCLUDES(wakeup_queue_lock_);
  void EnqueueFormatRequest(
      fuchsia::virtualaudio::Device::GetFormatCallback format_callback)
      __TA_EXCLUDES(wakeup_queue_lock_);
  void EnqueueBufferRequest(
      fuchsia::virtualaudio::Device::GetBufferCallback buffer_callback)
      __TA_EXCLUDES(wakeup_queue_lock_);
  void EnqueuePositionRequest(
      fuchsia::virtualaudio::Device::GetPositionCallback position_callback)
      __TA_EXCLUDES(wakeup_queue_lock_);

  static fbl::RefPtr<VirtualAudioStream> CreateStream(
      VirtualAudioDeviceImpl* owner, zx_device_t* devnode, bool is_input);

  // Only set by DeviceImpl -- on dtor, Disable or Remove
  bool shutdown_by_parent_ = false;

 protected:
  friend class ::audio::SimpleAudioStream;
  friend class fbl::RefPtr<VirtualAudioStream>;

  VirtualAudioStream(VirtualAudioDeviceImpl* parent, zx_device_t* dev_node,
                     bool is_input)
      : ::audio::SimpleAudioStream(dev_node, is_input), parent_(parent) {}
  ~VirtualAudioStream() override;

  zx_status_t Init() __TA_REQUIRES(domain_->token()) override;
  zx_status_t InitPost() override;

  zx_status_t ChangeFormat(const ::audio::audio_proto::StreamSetFmtReq& req)
      __TA_REQUIRES(domain_->token()) override;
  zx_status_t SetGain(const ::audio::audio_proto::SetGainReq& req)
      __TA_REQUIRES(domain_->token()) override;

  zx_status_t GetBuffer(const ::audio::audio_proto::RingBufGetBufferReq& req,
                        uint32_t* out_num_rb_frames, zx::vmo* out_buffer)
      __TA_REQUIRES(domain_->token()) override;

  zx_status_t Start(uint64_t* out_start_time)
      __TA_REQUIRES(domain_->token()) override;
  zx_status_t Stop() __TA_REQUIRES(domain_->token()) override;

  void ShutdownHook() __TA_REQUIRES(domain_->token()) override;
  // RingBufferShutdown() is unneeded: no hardware shutdown tasks needed...

  zx_status_t ProcessRingNotification() __TA_REQUIRES(domain_->token());

  enum class PlugType { Plug, Unplug };

  void HandlePlugChanges() __TA_REQUIRES(domain_->token())
      __TA_EXCLUDES(wakeup_queue_lock_);
  void HandlePlugChange(PlugType plug_change) __TA_REQUIRES(domain_->token());

  void HandleGainRequests() __TA_REQUIRES(domain_->token())
      __TA_EXCLUDES(wakeup_queue_lock_);
  void HandleFormatRequests() __TA_REQUIRES(domain_->token())
      __TA_EXCLUDES(wakeup_queue_lock_);
  void HandleBufferRequests() __TA_REQUIRES(domain_->token())
      __TA_EXCLUDES(wakeup_queue_lock_);
  void HandlePositionRequests() __TA_REQUIRES(domain_->token())
      __TA_EXCLUDES(wakeup_queue_lock_);

  // Accessed in GetBuffer, defended by token.
  fzl::VmoMapper ring_buffer_mapper_ __TA_GUARDED(domain_->token());
  zx::vmo ring_buffer_vmo_ __TA_GUARDED(domain_->token());
  uint32_t num_ring_buffer_frames_ __TA_GUARDED(domain_->token()) = 0;

  uint32_t max_buffer_frames_ __TA_GUARDED(domain_->token());
  uint32_t min_buffer_frames_ __TA_GUARDED(domain_->token());
  uint32_t modulo_buffer_frames_ __TA_GUARDED(domain_->token());

  fbl::RefPtr<dispatcher::Timer> notify_timer_;
  uint32_t us_per_notification_ __TA_GUARDED(domain_->token()) = 0;
  uint32_t notifications_per_ring_ __TA_GUARDED(domain_->token()) = 0;
  zx::time start_time_ __TA_GUARDED(domain_->token());

  uint32_t bytes_per_sec_ __TA_GUARDED(domain_->token()) = 0;
  uint32_t frame_rate_ __TA_GUARDED(domain_->token()) = 0;
  audio_sample_format_t sample_format_ __TA_GUARDED(domain_->token()) = 0;
  uint32_t num_channels_ __TA_GUARDED(domain_->token()) = 0;

  VirtualAudioDeviceImpl* parent_ __TA_GUARDED(domain_->token());

  fbl::Mutex wakeup_queue_lock_ __TA_ACQUIRED_AFTER(domain_->token());

  // TODO(mpuryear): Refactor to a single queue of lambdas to dedupe this code.
  fbl::RefPtr<::dispatcher::WakeupEvent> plug_change_wakeup_;
  std::deque<PlugType> plug_queue_ __TA_GUARDED(wakeup_queue_lock_);

  fbl::RefPtr<::dispatcher::WakeupEvent> gain_request_wakeup_;
  std::deque<fuchsia::virtualaudio::Device::GetGainCallback> gain_queue_
      __TA_GUARDED(wakeup_queue_lock_);

  fbl::RefPtr<::dispatcher::WakeupEvent> format_request_wakeup_;
  std::deque<fuchsia::virtualaudio::Device::GetFormatCallback> format_queue_
      __TA_GUARDED(wakeup_queue_lock_);

  fbl::RefPtr<::dispatcher::WakeupEvent> buffer_request_wakeup_;
  std::deque<fuchsia::virtualaudio::Device::GetBufferCallback> buffer_queue_
      __TA_GUARDED(wakeup_queue_lock_);

  fbl::RefPtr<::dispatcher::WakeupEvent> position_request_wakeup_;
  std::deque<fuchsia::virtualaudio::Device::GetPositionCallback> position_queue_
      __TA_GUARDED(wakeup_queue_lock_);
};

}  // namespace virtual_audio

#endif  // GARNET_DRIVERS_AUDIO_VIRTUAL_AUDIO_VIRTUAL_AUDIO_STREAM_H_
