// 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_V1_AUDIO_OBJECT_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_V1_AUDIO_OBJECT_H_

#include <lib/fit/function.h>

#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>

#include "src/lib/fxl/synchronization/thread_annotations.h"
#include "src/media/audio/audio_core/shared/mixer/mixer.h"
#include "src/media/audio/audio_core/shared/pipeline_config.h"
#include "src/media/audio/audio_core/shared/stream_usage.h"
#include "src/media/audio/audio_core/shared/volume_curve.h"
#include "src/media/audio/audio_core/v1/stream.h"
#include "src/media/audio/audio_core/v1/threading_model.h"
#include "src/media/audio/lib/format/format.h"

namespace media::audio {

// The simple base class for 4 major types of audio objects in the mixer: Outputs, Inputs,
// AudioRenderers and AudioCapturers. It ensures that each is intrusively ref-counted, and remembers
// its type so that it may be safely downcast from generic object to something more specific.
class AudioObject {
 public:
  // Disallow copy, assign, and move.
  AudioObject& operator=(AudioObject) = delete;
  AudioObject(const AudioObject&) = delete;
  AudioObject(AudioObject&&) = delete;
  AudioObject& operator=(AudioObject&&) = delete;

  virtual ~AudioObject() = default;

  enum class Type {
    Output,
    Input,
    AudioRenderer,
    AudioCapturer,
  };

  // Initialize(Source|Dest)Link
  //
  // Called on the AudioCore's main message loop any time a source and a destination are being
  // linked via AudioObject::LinkObjects. By default, these hooks do nothing, but AudioObject
  // subclasses may use them to set the properties of a link (or reject the link) before the link
  // gets added to the source and destination link sets.
  //
  // For example, Sources like an AudioRenderer override InitializeDestLink in order to set the
  // source gain and to make a copy of their pending packet queue. Destinations like an output
  // override InitializeSourceLink in order to choose and initialize an appropriate resampling
  // filter.
  //
  // When initializing a source link, an implementor must provide a mixer and an ExecutionDomain
  // for that mixer to run in. The source object and their stream are provided.
  //
  // Returns ZX_OK if initialization succeeded, or an appropriate error code otherwise.
  virtual fpromise::result<std::pair<std::shared_ptr<Mixer>, ExecutionDomain*>, zx_status_t>
  InitializeSourceLink(const AudioObject& source, std::shared_ptr<ReadableStream> stream) {
    return fpromise::ok(std::make_pair(Mixer::NoOp(), nullptr));
  }
  virtual fpromise::result<std::shared_ptr<ReadableStream>, zx_status_t> InitializeDestLink(
      const AudioObject& dest) {
    return fpromise::ok(nullptr);
  }

  virtual void CleanupSourceLink(const AudioObject& source,
                                 std::shared_ptr<ReadableStream> stream) {}
  virtual void CleanupDestLink(const AudioObject& dest) {}

  // Called immediately after a new link is added to the object.
  virtual void OnLinkAdded() {}

  // Note: format() is subject to change and must only be accessed from the main message loop
  // thread. Outputs which are running on mixer threads should never access format() directly
  // from a mix thread. Instead, they should use the format which was assigned to the AudioLink
  // at the time the link was created.
  virtual std::optional<Format> format() const { return std::nullopt; }
  virtual std::optional<StreamUsage> usage() const { return std::nullopt; }
  virtual const PipelineConfig* pipeline_config() const { return nullptr; }

  bool format_valid() const { return format().has_value(); }

  AudioObject::Type type() const { return type_; }

  bool is_output() const { return type() == Type::Output; }
  bool is_input() const { return type() == Type::Input; }
  bool is_audio_renderer() const { return type() == Type::AudioRenderer; }
  bool is_audio_capturer() const { return type() == Type::AudioCapturer; }

 protected:
  explicit AudioObject(Type type) : type_(type) {}

 private:
  const Type type_;
};

inline std::ostream& operator<<(std::ostream& out, const AudioObject::Type& type) {
  switch (type) {
    case AudioObject::Type::AudioCapturer:
      return (out << "capturer");
    case AudioObject::Type::AudioRenderer:
      return (out << "renderer");
    case AudioObject::Type::Input:
      return (out << " input  ");
    case AudioObject::Type::Output:
      return (out << " output ");
  }
}

}  // namespace media::audio

#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_V1_AUDIO_OBJECT_H_
