// 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_OUTPUT_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_AUDIO_OUTPUT_H_

#include <lib/async/cpp/task.h>
#include <lib/async/cpp/time.h>
#include <lib/zx/time.h>

#include <optional>

#include "src/media/audio/audio_core/audio_clock_manager.h"
#include "src/media/audio/audio_core/audio_device.h"
#include "src/media/audio/audio_core/output_pipeline.h"
#include "src/media/audio/audio_core/process_config.h"
#include "src/media/audio/audio_core/reporter.h"
#include "src/media/audio/lib/timeline/timeline_function.h"

namespace media::audio {

class Packet;

class AudioOutput : public AudioDevice {
 public:
  ~AudioOutput() override = default;

  fit::promise<void, fuchsia::media::audio::UpdateEffectError> UpdateEffect(
      const std::string& instance_name, const std::string& config) override;

  // Replace the existing DeviceProfile and restart the OutputPipeline, for tuning purposes.
  fit::promise<void, zx_status_t> UpdateDeviceProfile(
      const DeviceConfig::OutputDeviceProfile::Parameters& params) override;

  OutputPipeline* output_pipeline() const { return pipeline_.get(); }

  // |media::audio::AudioDevice|
  void SetGainInfo(const fuchsia::media::AudioGainInfo& info,
                   fuchsia::media::AudioGainValidFlags set_flags) override;

 protected:
  AudioOutput(const std::string& name, ThreadingModel* threading_model, DeviceRegistry* registry,
              LinkMatrix* link_matrix, std::shared_ptr<AudioClockManager> clock_manager);
  AudioOutput(const std::string& name, ThreadingModel* threading_model, DeviceRegistry* registry,
              LinkMatrix* link_matrix, std::shared_ptr<AudioClockManager> clock_manager,
              std::unique_ptr<AudioDriver>);

  void Process() FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain().token());
  Reporter::OutputDevice& reporter() { return *reporter_; }

  // |media::audio::AudioObject|
  //
  // If we're initializing a source link, then we're connecting a renderer to this output. Else
  // if we're initializing a dest link, then we're being connected as a loopback so we should return
  // our loopback stream.
  fit::result<std::pair<std::shared_ptr<Mixer>, ExecutionDomain*>, zx_status_t>
  InitializeSourceLink(const AudioObject& source, std::shared_ptr<ReadableStream> stream) final;
  void CleanupSourceLink(const AudioObject& source, std::shared_ptr<ReadableStream> stream) final;
  fit::result<std::shared_ptr<ReadableStream>, zx_status_t> InitializeDestLink(
      const AudioObject& dest) override;

  // Mark this output as needing to be mixed at the specified future time.
  // async PostForTime requires a time in the CLOCK_MONOTONIC timebase, so we use that here.
  void SetNextSchedTimeMono(zx::time next_sched_time_mono) {
    next_sched_time_mono_ = next_sched_time_mono;
  }

  inline void ClearNextSchedTime() { next_sched_time_mono_ = std::nullopt; }

  void SetupMixTask(const DeviceConfig::OutputDeviceProfile& profile, size_t max_block_size_frames,
                    TimelineFunction device_reference_clock_to_fractional_frame)
      FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain().token());
  virtual std::unique_ptr<OutputPipeline> CreateOutputPipeline(
      const PipelineConfig& config, const VolumeCurve& volume_curve, size_t max_block_size_frames,
      TimelineFunction device_reference_clock_to_fractional_frame, AudioClock& ref_clock);

  void Cleanup() override FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain().token());

  struct FrameSpan {
    int64_t start;
    uint64_t length;
    bool is_mute;
  };

  // Start mixing frames for a periodic mix job. This is called internally during the periodic mix
  // task for this output. Implementations can control mix behavior in the following ways:
  //
  // If |std::nullopt| is returned, then no frames will be mixed. Instead all inputs will be trimmed
  // such that any client audio packets that will have been fully consumed by |device_ref_time| will
  // still be released. There will be no call to |FinishMixJob|.
  //
  // If the retuned optional contains a FrameSpan with |is_mute| set to true, then no frames will
  // be mixed. Instead all inputs will be trimmed such that any client audio packets that will have
  // been fully consumed by |device_ref_time| will still be released. |FinishMixJob| will be called
  // with the returned FrameSpan and a null payload buffer. It is the responsibility of
  // |FinishMixJob| to produce the silence for the FrameSpan.
  //
  // If the retuned optional contains a FrameSpan with |is_mute| set to false, then the mix
  // pipeline will be advanced by the requested frame region. |FinishMixJob| will be called with a
  // FrameSpan that is 'at most' as long as the span in |StartMixJob|, but this length may be
  // reduced if the pipeline is unable to fill a single, contiguous buffer will all the frames
  // requested. If the entire region in StartMixJob is unable to be populated in a single pass, then
  // StartMixJob will be called again to process any remaining frames.
  virtual std::optional<AudioOutput::FrameSpan> StartMixJob(zx::time device_ref_time)
      FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain().token()) = 0;

  // Finish a mix job by moving the frame range span |span| into the hardware ring buffer using
  // |buffer| as a source. |span.start| should be a value that was provided in |StartMixJob| and
  // |span.length| should be at most the value returned from |StartMixJob|, but may be adjusted
  // downwards if the full range cannot be produced.
  //
  // If |span.is_mute| is false, |buffer| must contain |span.length * channels| floating point
  // samples of audio data.
  //
  // If |span.is_mute| is true, then |buffer| is ignored and instead silence will be inserted
  // into the ring buffer for the frame range in |span|.
  virtual void FinishMixJob(const AudioOutput::FrameSpan& span, const float* buffer)
      FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain().token()) = 0;

  // The maximum amount of time it can take to run all pending mix jobs when a device
  // wakes up to process pending jobs.
  virtual zx::duration MixDeadline() const FXL_EXCLUSIVE_LOCKS_REQUIRED(mix_domain().token()) = 0;

 private:
  // Timer used to schedule periodic mixing.
  void MixTimerThunk() {
    OBTAIN_EXECUTION_DOMAIN_TOKEN(token, &mix_domain());
    Process();
  }
  async::TaskClosureMethod<AudioOutput, &AudioOutput::MixTimerThunk> mix_timer_
      FXL_GUARDED_BY(mix_domain().token()){this};

  std::optional<zx::time> next_sched_time_mono_;
  size_t max_block_size_frames_;

  std::unique_ptr<OutputPipeline> pipeline_;
  Reporter::Container<Reporter::OutputDevice, Reporter::kObjectsToCache>::Ptr reporter_;
  ThreadCpuTimer cpu_timer_;
};

}  // namespace media::audio

#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_AUDIO_OUTPUT_H_
