// Copyright 2018 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_LIB_EFFECTS_LOADER_EFFECTS_PROCESSOR_H_
#define SRC_MEDIA_AUDIO_LIB_EFFECTS_LOADER_EFFECTS_PROCESSOR_H_

#include <zircon/types.h>

#include <vector>

#include "src/media/audio/lib/effects_loader/effect.h"

namespace media::audio {

// EffectsProcessor represents a queue of active effect instances and manages chaining calls of
// Process/ProcessInPlace through a chain of effects.
//
// This class is designed to be used synchronously and is not explicitly multi-thread-safe.
class EffectsProcessor {
 public:
  // Creates a new, empty effects processor.
  EffectsProcessor() = default;

  // Allow move.
  EffectsProcessor(EffectsProcessor&& o) noexcept;
  EffectsProcessor& operator=(EffectsProcessor&& o) noexcept;

  // Disallow copy.
  EffectsProcessor(const EffectsProcessor&) = delete;
  EffectsProcessor& operator=(const EffectsProcessor&) = delete;

  // Adds an `Effect` to the end of the queue of effects included in this processor.
  //
  // When the first `Effect` is added, that effects input channels becomes the input to the entire
  // processor. Likewise that effects output channels becomes the processors output channels.
  //
  // When subsequent effects are added, the new effects input channels must match exactly the out-
  // put channels of last added effect. The output channels for the processor will be updated to
  // match the output channels of the newly added effect.
  //
  // Currently AddEffect will fail if an Effect has channels_in != channels_out (ex: all effects
  // must do in-place processing). This is a short-term limitation that will be lifted in the
  // future.
  //
  // Aborts if `e` is an invalid `Effect`.
  zx_status_t AddEffect(Effect e);

  // Returns the number of active instances in the enclosed effect chain.
  [[nodiscard]] uint16_t size() const { return effects_chain_.size(); }

  // Returns the number of input channels for this effect. This will be the number of channels
  // expected for input frames to `ProcessInPlace`.
  //
  // Returns 0 if this processor has no effects.
  [[nodiscard]] uint32_t channels_in() const { return channels_in_; }

  // Returns the number of output channels for this effect. Currently this always equals
  // `channels_in()`.
  //
  // Returns 0 if this processor has no effects.
  [[nodiscard]] uint32_t channels_out() const { return channels_out_; }

  [[nodiscard]] auto begin() { return effects_chain_.begin(); }
  [[nodiscard]] auto end() { return effects_chain_.end(); }
  [[nodiscard]] auto cbegin() const { return effects_chain_.cbegin(); }
  [[nodiscard]] auto cend() const { return effects_chain_.cend(); }

  // Returns the instance at the specified (zero-based) position in the chain.
  [[nodiscard]] const Effect& GetEffectAt(size_t position) const;

  // These maps directly to the corresponding ABI call, for each instance.
  zx_status_t ProcessInPlace(uint32_t num_frames, float* audio_buff_in_out) const;
  zx_status_t Flush() const;

 private:
  std::vector<Effect> effects_chain_;
  uint32_t channels_in_ = 0;
  uint32_t channels_out_ = 0;
};

}  // namespace media::audio

#endif  // SRC_MEDIA_AUDIO_LIB_EFFECTS_LOADER_EFFECTS_PROCESSOR_H_
