// 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_AUDIO_AUDIO_CORE_OUTPUT_PIPELINE_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_OUTPUT_PIPELINE_H_

#include <lib/syslog/cpp/macros.h>
#include <lib/trace/event.h>

#include <vector>

#include <fbl/ref_ptr.h>

#include "src/media/audio/audio_core/audio_clock.h"
#include "src/media/audio/audio_core/effects_stage.h"
#include "src/media/audio/audio_core/mix_stage.h"
#include "src/media/audio/audio_core/pipeline_config.h"
#include "src/media/audio/audio_core/stream.h"
#include "src/media/audio/audio_core/stream_usage.h"
#include "src/media/audio/audio_core/volume_curve.h"
#include "src/media/audio/lib/timeline/timeline_function.h"

namespace media::audio {

class OutputPipeline : public ReadableStream {
 public:
  explicit OutputPipeline(Format format) : ReadableStream(format) {}
  ~OutputPipeline() override = default;

  // Returns the loopback |ReadableStream| for this pipeline.
  virtual std::shared_ptr<ReadableStream> loopback() const = 0;

  // Adds |stream| as an input to be mixed. The given |usage| will indicate where in the pipeline
  // this stream will be routed.
  virtual std::shared_ptr<Mixer> AddInput(
      std::shared_ptr<ReadableStream> stream, const StreamUsage& usage,
      std::optional<float> initial_dest_gain_db = std::nullopt,
      Mixer::Resampler sampler_hint = Mixer::Resampler::Default) = 0;

  // Removes |stream| from the pipeline.
  //
  // It is an error to call |RemoveInput| without exactly one preceeding call to |AddInput| with the
  // same |stream|.
  virtual void RemoveInput(const ReadableStream& stream) = 0;

  // Sets the configuration of all effects with the given instance name.
  virtual fit::result<void, fuchsia::media::audio::UpdateEffectError> UpdateEffect(
      const std::string& instance_name, const std::string& config) = 0;
};

class OutputPipelineImpl : public OutputPipeline {
 public:
  // Creates an |OutputPipeline| based on the specification in |config|. The pipeline will
  // ultimately produce output frames via |ReadLock| in the |output_format| requested.
  //
  // |max_block_size_frames| is the largest contiguous region that may be returned from
  // |ReadLock|. If a caller requests a frame region of more that |max_block_size_frames|, then
  // the pipeline will truncate this to only |max_block_size_frames| and the caller will have to
  // call |ReadLock| again to mix the subsequent frames.
  //
  // |ref_clock_to_fractional_frame| is a timeline function that will compute the output frame
  // number (in fixed point format with 13 bits of fractional precision) based on a reference
  // timestamp.
  //
  // The |sampler| is optionally used to select the type of sampler to be used when joining
  // mix stages together.
  OutputPipelineImpl(const PipelineConfig& config, const VolumeCurve& volume_curve,
                     uint32_t max_block_size_frames,
                     TimelineFunction ref_time_to_frac_presentation_frame, AudioClock& audio_clock,
                     Mixer::Resampler sampler = Mixer::Resampler::Default);
  ~OutputPipelineImpl() override = default;

  // |media::audio::OutputPipeline|
  std::shared_ptr<ReadableStream> loopback() const override { return state_.loopback; }
  std::shared_ptr<Mixer> AddInput(
      std::shared_ptr<ReadableStream> stream, const StreamUsage& usage,
      std::optional<float> initial_dest_gain_db = std::nullopt,
      Mixer::Resampler sampler_hint = Mixer::Resampler::Default) override;
  void RemoveInput(const ReadableStream& stream) override;
  fit::result<void, fuchsia::media::audio::UpdateEffectError> UpdateEffect(
      const std::string& instance_name, const std::string& config) override;

  // |media::audio::ReadableStream|
  std::optional<ReadableStream::Buffer> ReadLock(Fixed dest_frame, size_t frame_count) override {
    TRACE_DURATION("audio", "OutputPipeline::ReadLock");
    FX_DCHECK(state_.stream);
    return state_.stream->ReadLock(dest_frame, frame_count);
  }
  void Trim(Fixed dest_frame) override {
    TRACE_DURATION("audio", "OutputPipeline::Trim");
    FX_CHECK(state_.stream);
    state_.stream->Trim(dest_frame);
  }
  TimelineFunctionSnapshot ref_time_to_frac_presentation_frame() const override {
    TRACE_DURATION("audio", "OutputPipeline::ref_time_to_frac_presentation_frame");
    FX_DCHECK(state_.stream);
    return state_.stream->ref_time_to_frac_presentation_frame();
  }
  void SetPresentationDelay(zx::duration external_delay) override {
    ReadableStream::SetPresentationDelay(external_delay);
    state_.stream->SetPresentationDelay(external_delay);
  }
  AudioClock& reference_clock() override { return state_.audio_clock; }

 private:
  struct State {
    State(const PipelineConfig& config, const VolumeCurve& curve, uint32_t max_block_size_frames,
          TimelineFunction ref_clock_to_fractional_frame, AudioClock& clock,
          Mixer::Resampler sampler);

    std::shared_ptr<ReadableStream> CreateMixStage(
        const PipelineConfig::MixGroup& spec, const VolumeCurve& volume_curve, uint32_t block_size,
        fbl::RefPtr<VersionedTimelineFunction> ref_clock_to_output_frame, AudioClock& clock,
        uint32_t* usage_mask, Mixer::Resampler sampler);

    std::vector<std::pair<std::shared_ptr<MixStage>, std::vector<StreamUsage>>> mix_stages;
    std::vector<std::shared_ptr<EffectsStage>> effects_stages;
    std::vector<std::pair<std::shared_ptr<ReadableStream>, StreamUsage>> streams;

    // This is the root of the mix graph. The other mix stages must be reachable from this node
    // to actually get mixed.
    std::shared_ptr<ReadableStream> stream;

    std::shared_ptr<ReadableStream> loopback;

    AudioClock& audio_clock;
  };

  OutputPipelineImpl(State state);

  MixStage& LookupStageForUsage(const StreamUsage& usage);

  State state_;
};

}  // namespace media::audio

#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_OUTPUT_PIPELINE_H_
