// Copyright 2017 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_BASE_CAPTURER_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_BASE_CAPTURER_H_

#include <fuchsia/media/audio/cpp/fidl.h>
#include <fuchsia/media/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/zx/clock.h>

#include <atomic>
#include <memory>
#include <mutex>

#include <fbl/intrusive_double_list.h>

#include "src/media/audio/audio_core/audio_clock.h"
#include "src/media/audio/audio_core/audio_object.h"
#include "src/media/audio/audio_core/capture_packet_queue.h"
#include "src/media/audio/audio_core/context.h"
#include "src/media/audio/audio_core/mixer/mixer.h"
#include "src/media/audio/audio_core/mixer/output_producer.h"
#include "src/media/audio/audio_core/reporter.h"
#include "src/media/audio/audio_core/route_graph.h"
#include "src/media/audio/audio_core/stream_volume_manager.h"
#include "src/media/audio/audio_core/usage_settings.h"
#include "src/media/audio/audio_core/utils.h"
#include "src/media/audio/lib/timeline/timeline_function.h"
#include "src/media/audio/lib/timeline/timeline_rate.h"

namespace media::audio {

class BaseCapturer : public AudioObject,
                     public fuchsia::media::AudioCapturer,
                     public std::enable_shared_from_this<BaseCapturer> {
 public:
  AudioClock& reference_clock() { return audio_clock_; }

 protected:
  using RouteGraphRemover = void (RouteGraph::*)(const AudioObject&);
  BaseCapturer(std::optional<Format> format,
               fidl::InterfaceRequest<fuchsia::media::AudioCapturer> audio_capturer_request,
               Context* context);

  ~BaseCapturer() override;

  Context& context() const { return context_; }

  ExecutionDomain& mix_domain() const { return *mix_domain_; }

  // Notes about the BaseCapturer state machine.
  //
  // :: WaitingForVmo ::
  // AudioCapturers start in this mode. They should have a default capture mode
  // set, and will accept a mode change up until the point where they have a
  // shared payload VMO assigned to them. At this point they transition into the
  // OperatingSync state. Only the main service thread may transition out of
  // this state.
  //
  // :: OperatingSync ::
  // After a mode has been assigned and a shared payload VMO has provided, the
  // AudioCapturer is now operating in synchronous mode. Clients may provided
  // buffers to be filled using the CaptureAt method and may cancel these
  // buffers using the Flush method. They may also transition to asynchronous
  // mode by calling StartAsyncCapture, but only when there are no pending
  // buffers in flight. Only the main service thread may transition out of
  // this state.
  //
  // :: OperatingAsync ::
  // AudioCapturers enter OperatingAsync after a successful call to
  // StartAsyncCapture. Threads from the mix_domain allocate and fill pending
  // payload buffers, then signal the main service thread in order to send them
  // back to the client over the AudioCapturerClient interface provided when
  // starting. CaptureAt and Flush are illegal operations while in this state.
  // clients may begin the process of returning to synchronous capture mode by
  // calling StopAsyncCapture. Only the main service thread may transition out
  // of this state.
  //
  // :: AsyncStopping ::
  // AudioCapturers enter AsyncStopping after a successful call to
  // StopAsyncCapture. A thread from the mix_domain will handle the details of
  // stopping, including transferring all partially filled pending buffers to
  // the finished queue. Aside from setting the gain, all operations are illegal
  // while the AudioCapturer is in the process of stopping. Once the mix domain
  // thread has finished cleaning up, it will transition to the
  // AsyncStoppingCallbackPending state and signal the main service thread in
  // order to complete the process. Only a mix domain thread may transition out
  // of this state.
  //
  // :: AsyncStoppingCallbackPending ::
  // AudioCapturers enter AsyncStoppingCallbackPending after a mix domain thread
  // has finished the process of shutting down the capture process and is ready
  // to signal to the client that the AudioCapturer is now in synchronous
  // capture mode again. The main service thread will send all partially and
  // completely filled buffers to the user, ensuring that there is at least one
  // buffer sent indicating end-of-stream, even if that buffer needs to be of
  // zero length. Finally, the main service thread will signal that the stopping
  // process is finished using the client supplied callback (if any), and
  // finally transition back to the OperatingSync state.
  enum class State {
    WaitingForVmo,
    OperatingSync,
    OperatingAsync,
    AsyncStopping,
    AsyncStoppingCallbackPending,
    Shutdown,
  };
  State capture_state() const { return state_.load(); }

  bool has_pending_packets() {
    auto pq = packet_queue();
    return pq && pq->PendingSize() > 0;
  }
  bool IsOperating();

  void UpdateFormat(Format format) FXL_LOCKS_EXCLUDED(mix_domain_->token());

  // Removes the capturer from its owner, the route graph, triggering shutdown and drop.
  void BeginShutdown();

  virtual void ReportStart() {}
  virtual void ReportStop() {}
  virtual void OnStateChanged(State old_state, State new_stage);
  virtual void SetRoutingProfile(bool routable) = 0;

  static bool StateIsRoutable(BaseCapturer::State state) {
    return state != BaseCapturer::State::WaitingForVmo && state != BaseCapturer::State::Shutdown;
  }

  // |media::audio::AudioObject|
  fit::result<std::pair<std::shared_ptr<Mixer>, ExecutionDomain*>, zx_status_t>
  InitializeSourceLink(const AudioObject& source, std::shared_ptr<ReadableStream> stream) override;
  void CleanupSourceLink(const AudioObject& source,
                         std::shared_ptr<ReadableStream> stream) override;
  void OnLinkAdded() override;

  fidl::Binding<fuchsia::media::AudioCapturer>& binding() { return binding_; }

  // AudioCore treats client-provided clocks as not-rate-adjustable.
  void SetClock(AudioClock audio_clock) { audio_clock_ = std::move(audio_clock); }

  Reporter::Capturer& reporter() { return *reporter_; }

 private:
  void UpdateState(State new_state);

  // |fuchsia::media::AudioCapturer|
  void GetStreamType(GetStreamTypeCallback cbk) final;
  void AddPayloadBuffer(uint32_t id, zx::vmo payload_buf_vmo) final;
  void RemovePayloadBuffer(uint32_t id) final;
  void GetReferenceClock(GetReferenceClockCallback callback) final;
  void CaptureAt(uint32_t payload_buffer_id, uint32_t offset_frames, uint32_t num_frames,
                 CaptureAtCallback cbk) final;
  void ReleasePacket(fuchsia::media::StreamPacket packet) final;
  void DiscardAllPackets(DiscardAllPacketsCallback cbk) final;
  void DiscardAllPacketsNoReply() final;
  void StartAsyncCapture(uint32_t frames_per_packet) final;
  void StopAsyncCapture(StopAsyncCaptureCallback cbk) final;
  void StopAsyncCaptureNoReply() final;

  // Methods used by capture/mixer thread(s). Must be called from mix_domain.
  zx_status_t Process() FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain_->token());
  void DoStopAsyncCapture() FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain_->token());
  void ShutdownFromMixDomain() FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain_->token());
  void ReportOverflow(zx::time start_time, zx::time end_time)
      FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain_->token());

  // Thunk to send ready packets back to the user, and to finish an async
  // mode stop operation.
  void FinishAsyncStopThunk() FXL_LOCKS_EXCLUDED(mix_domain_->token());
  void FinishBuffersThunk() FXL_LOCKS_EXCLUDED(mix_domain_->token());

  // Helper function used to return a set of ready packets to a user.
  void FinishBuffers() FXL_LOCKS_EXCLUDED(mix_domain_->token());

  fit::promise<> Cleanup() FXL_LOCKS_EXCLUDED(mix_domain_->token());
  void CleanupFromMixThread() FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain_->token());
  void MixTimerThunk() {
    OBTAIN_EXECUTION_DOMAIN_TOKEN(token, mix_domain_);
    Process();
  }

  void RecomputePresentationDelay();

  TimelineRate dest_frames_to_ref_clock_rate() {
    return TimelineRate(ZX_SEC(1), format_.frames_per_second());
  }

  fidl::Binding<fuchsia::media::AudioCapturer> binding_;
  Context& context_;
  ThreadingModel::OwnedDomainPtr mix_domain_;
  std::atomic<State> state_;
  zx::duration presentation_delay_;

  // Capture format and gain state.
  Format format_;
  uint32_t max_frames_per_capture_;

  // Shared buffer state
  fzl::VmoMapper payload_buf_;

  WakeupEvent mix_wakeup_;
  WakeupEvent ready_packets_wakeup_;
  async::TaskClosureMethod<BaseCapturer, &BaseCapturer::MixTimerThunk> mix_timer_
      FXL_GUARDED_BY(mix_domain_->token()){this};

  // Queue of pending and ready packets.
  //
  // Concurrency notes: Initially this is nullptr. When we transition to state OperatingSync
  // or OperatingAsync, we create a new queue and start mixing. Later, in response to a FIDL
  // call, we might change operating modes from Sync -> Async or visa versa. To do this, we
  // create a new queue, but as this happens, the mixer may be concurrently mixing on the old
  // queue. We use a shared_ptr to ensure that the mixer can hold a valid reference for the
  // duration of the mix operation, even in the presence of a concurrent mode switch.
  //
  // To illustrate:
  //
  //   fidl_thread {
  //     // Switch from sync -> async.
  //     packet_queue()->DiscardPendingPackets();
  //     set_packet_queue_(CapturePacketQueue::CreatePreallocated(...));
  //   }
  //   mixer_thread {
  //     auto pq = packet_queue();
  //     auto state = pq->NextMixerJob();
  //     // ... FIDL thread might run here ...
  //     auto status = pq->FinishMixerJob(state);
  //     // ... will have status == Discarded ...
  //   }
  //
  std::mutex packet_queue_lock_;
  std::shared_ptr<CapturePacketQueue> packet_queue_ FXL_GUARDED_BY(packet_queue_lock_);

  std::shared_ptr<CapturePacketQueue> packet_queue() {
    std::lock_guard<std::mutex> lock(packet_queue_lock_);
    return packet_queue_;
  }
  void set_packet_queue(std::shared_ptr<CapturePacketQueue> pq) {
    std::lock_guard<std::mutex> lock(packet_queue_lock_);
    packet_queue_ = pq;
  }

  // Intermediate mixing buffer and output producer
  std::unique_ptr<OutputProducer> output_producer_;

  std::vector<LinkMatrix::LinkHandle> source_links_ FXL_GUARDED_BY(mix_domain_->token());

  // Capture bookkeeping
  fbl::RefPtr<VersionedTimelineFunction> ref_pts_to_fractional_frame_ =
      fbl::MakeRefCounted<VersionedTimelineFunction>();
  bool discontinuity_ FXL_GUARDED_BY(mix_domain_->token()) = true;
  int64_t frame_pointer_ FXL_GUARDED_BY(mix_domain_->token()) = 0;
  uint64_t overflow_count_ FXL_GUARDED_BY(mix_domain_->token()) = 0;

  StopAsyncCaptureCallback pending_async_stop_cbk_;

  std::shared_ptr<MixStage> mix_stage_;
  Reporter::Container<Reporter::Capturer, Reporter::kObjectsToCache>::Ptr reporter_;

  AudioClock audio_clock_;
};

}  // namespace media::audio

#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_BASE_CAPTURER_H_
