// 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_REPORTER_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_REPORTER_H_

#include <fuchsia/cobalt/cpp/fidl.h>
#include <fuchsia/media/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/sys/inspect/cpp/component.h>

#include <mutex>
#include <queue>
#include <set>
#include <unordered_map>

#include "src/lib/cobalt/cpp/cobalt_logger.h"
#include "src/lib/fxl/synchronization/thread_annotations.h"
#include "src/media/audio/audio_core/audio_admin.h"
#include "src/media/audio/audio_core/stream_usage.h"
#include "src/media/audio/audio_core/threading_model.h"
#include "src/media/audio/lib/format/format.h"

namespace media::audio {

class AudioDriver;

// A singleton instance of |Reporter| handles instrumentation concerns (e.g.
// exposing information via inspect, cobalt, etc) for an audio_core instance.
// The idea is to make instrumentation as simple as possible for the code that
// does the real work. The singleton can be accessed via
//
//   Reporter::Singleton()
//
// Given a Reporter, reporting objects can be created through the Create*()
// methods. Each reporting object is intended to mirror a single object within
// audio_core, such as an AudioRenderer -- the reporting object should live
// exactly as long as its parent audio_core object. In addition to Create*()
// methods, there are FailedTo*() methods that report when an object could not
// be created.
//
// The singleton object always exists: it does not need to be created. However,
// the singleton needs to be initialized, via Reporter::InitializeSingleton().
// Before that static method is called, all reporting objects created by the
// singleton will be no-ops.
//
// The lifetime of each reporting object is divided into sessions. Roughly
// speaking, a session corresponds to a contiguous time spent processing audio.
// For example, for an AudioRenderer, this is the time between Play and Pause events.
// Session lifetimes are controlled by StartSession and StopSession methods.
//
// All times are relative to the system monotonic clock.
//
// This class is fully thread safe, including all static methods and all methods
// on reporting objects.
//
class Reporter {
 public:
  static Reporter& Singleton();
  static void InitializeSingleton(sys::ComponentContext& component_context,
                                  ThreadingModel& threading_model);

  class Device {
   public:
    virtual ~Device() = default;

    virtual void Destroy() = 0;

    virtual void StartSession(zx::time start_time) = 0;
    virtual void StopSession(zx::time stop_time) = 0;

    virtual void SetDriverInfo(const AudioDriver& driver) = 0;
    virtual void SetGainInfo(const fuchsia::media::AudioGainInfo& gain_info,
                             fuchsia::media::AudioGainValidFlags set_flags) = 0;
  };

  class OutputDevice : public Device {
   public:
    virtual void DeviceUnderflow(zx::time start_time, zx::time end_time) = 0;
    virtual void PipelineUnderflow(zx::time start_time, zx::time end_time) = 0;
  };

  class InputDevice : public Device {};

  class Renderer {
   public:
    virtual ~Renderer() = default;

    virtual void Destroy() = 0;

    virtual void StartSession(zx::time start_time) = 0;
    virtual void StopSession(zx::time stop_time) = 0;

    virtual void SetUsage(RenderUsage usage) = 0;
    virtual void SetFormat(const Format& format) = 0;
    virtual void SetGain(float gain_db) = 0;
    virtual void SetGainWithRamp(float gain_db, zx::duration duration,
                                 fuchsia::media::audio::RampType ramp_type) = 0;
    virtual void SetFinalGain(float gain_db) = 0;
    virtual void SetMute(bool muted) = 0;
    virtual void SetMinLeadTime(zx::duration min_lead_time) = 0;
    virtual void SetPtsContinuityThreshold(float threshold_seconds) = 0;

    virtual void AddPayloadBuffer(uint32_t buffer_id, uint64_t size) = 0;
    virtual void RemovePayloadBuffer(uint32_t buffer_id) = 0;
    virtual void SendPacket(const fuchsia::media::StreamPacket& packet) = 0;
    virtual void Underflow(zx::time start_time, zx::time end_time) = 0;
  };

  class Capturer {
   public:
    virtual ~Capturer() = default;

    virtual void Destroy() = 0;

    virtual void StartSession(zx::time start_time) = 0;
    virtual void StopSession(zx::time stop_time) = 0;

    virtual void SetUsage(CaptureUsage usage) = 0;
    virtual void SetFormat(const Format& format) = 0;
    virtual void SetGain(float gain_db) = 0;
    virtual void SetGainWithRamp(float gain_db, zx::duration duration,
                                 fuchsia::media::audio::RampType ramp_type) = 0;
    virtual void SetMute(bool muted) = 0;
    virtual void SetMinFenceTime(zx::duration min_fence_time) = 0;

    virtual void AddPayloadBuffer(uint32_t buffer_id, uint64_t size) = 0;
    virtual void SendPacket(const fuchsia::media::StreamPacket& packet) = 0;
    virtual void Overflow(zx::time start_time, zx::time end_time) = 0;
  };

  class VolumeControl {
   public:
    virtual ~VolumeControl() = default;

    virtual void Destroy() = 0;

    virtual void SetVolumeMute(float volume, bool mute) = 0;
    virtual void AddBinding(std::string name) = 0;
  };

  // This class is an implementation detail.
  // Container::Ptr is a smart pointer that calls T::Destroy() when the Ptr is destructed.
  // The underlying object may be cached for some time afterwards.
  // ObjectsToCache is the number of destroyed objects to cache, in addition to the
  // current alive object.
  template <typename T, size_t ObjectsToCache>
  class Container {
   public:
    class Ptr {
     public:
      Ptr(Container<T, ObjectsToCache>* c, std::shared_ptr<T> p) : container_(c), ptr_(p) {}
      Ptr(const Ptr&) = delete;
      Ptr(Ptr&&) = default;
      ~Ptr() { Drop(); }

      Ptr& operator=(Ptr&& rhs) noexcept {
        Drop();
        ptr_ = std::move(rhs.ptr_);
        container_ = rhs.container_;
        rhs.container_ = nullptr;
        return *this;
      }

      T& operator*() const { return *ptr_; }
      T* operator->() const { return ptr_.get(); }

      void Drop() {
        if (ptr_) {
          ptr_->Destroy();
          container_->Kill(ptr_);
          ptr_ = nullptr;
        }
      }

     private:
      Container<T, ObjectsToCache>* container_ = nullptr;
      std::shared_ptr<T> ptr_;
    };

   private:
    friend class Reporter;
    friend class Ptr;

    Ptr New(T* object) {
      std::shared_ptr<T> ptr(object);
      std::lock_guard<std::mutex> lock(mutex_);
      alive_.insert(ptr);
      return Ptr(this, ptr);
    }

    void Kill(const std::shared_ptr<T>& ptr) {
      std::lock_guard<std::mutex> lock(mutex_);
      alive_.erase(ptr);
      while (dead_.size() >= ObjectsToCache) {
        dead_.pop();
      }
      dead_.push(ptr);
    }

    std::mutex mutex_;
    std::set<std::shared_ptr<T>> alive_ FXL_GUARDED_BY(mutex_);
    std::queue<std::shared_ptr<T>> dead_ FXL_GUARDED_BY(mutex_);
  };

  Reporter() {}
  Reporter(sys::ComponentContext& component_context, ThreadingModel& threading_model);

  static constexpr size_t kObjectsToCache = 4;
  static constexpr size_t kVolumeControlsToCache = 10;
  static constexpr size_t kActiveUsagePoliciesToCache = 10;

  Container<OutputDevice, kObjectsToCache>::Ptr CreateOutputDevice(const std::string& name,
                                                                   const std::string& thread_name);
  Container<InputDevice, kObjectsToCache>::Ptr CreateInputDevice(const std::string& name,
                                                                 const std::string& thread_name);
  Container<Renderer, kObjectsToCache>::Ptr CreateRenderer();
  Container<Capturer, kObjectsToCache>::Ptr CreateCapturer(const std::string& thread_name);
  Container<VolumeControl, kVolumeControlsToCache>::Ptr CreateVolumeControl();

  // Thermal state of Audio system.
  void SetNumThermalStates(size_t num);
  void SetThermalState(uint32_t state);

  // Audio policy logging of usage activity and behavior (none|duck|mute).
  void SetAudioPolicyBehaviorGain(AudioAdmin::BehaviorGain behavior_gain);
  void UpdateActiveUsagePolicy(const std::vector<fuchsia::media::Usage>& active_usages,
                               const AudioAdmin::RendererPolicies& renderer_policies,
                               const AudioAdmin::CapturerPolicies& capturer_policies);

  // Device creation failures.
  void FailedToOpenDevice(const std::string& name, bool is_input, int err);
  void FailedToObtainFdioServiceChannel(const std::string& name, bool is_input, zx_status_t status);
  void FailedToObtainStreamChannel(const std::string& name, bool is_input, zx_status_t status);
  void FailedToStartDevice(const std::string& name);

  // Mixer events which are not easily tied to a specific device or client.
  void MixerClockSkewDiscontinuity(zx::duration abs_clock_error);

  // Exported for tests.
  const inspect::Inspector& inspector() {
    std::lock_guard<std::mutex> lock(mutex_);
    return *impl_->inspector->inspector();
  }

 private:
  static constexpr size_t kThermalStatesToCache = 8;

  class OverflowUnderflowTracker;
  class ObjectTracker;
  class DeviceDriverInfo;
  class ThermalStateTransition;
  class ThermalStateTracker;
  class OutputDeviceImpl;
  class InputDeviceImpl;
  class ClientPort;
  class RendererImpl;
  class CapturerImpl;
  class VolumeControlImpl;
  class VolumeSetting;
  class ActiveUsagePolicy;
  class ActiveUsagePolicyTracker;
  struct Impl;

  friend class OverflowUnderflowTracker;
  friend class ObjectTracker;
  friend class OutputDeviceImpl;
  friend class InputDeviceImpl;
  friend class RendererImpl;
  friend class CapturerImpl;

  void InitInspect() FXL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
  void InitCobalt() FXL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);

  // This object contains internal state shared by multiple reporting objects.
  struct Impl {
    sys::ComponentContext& component_context;
    ThreadingModel& threading_model;
    std::unique_ptr<sys::ComponentInspector> inspector;
    std::unique_ptr<cobalt::CobaltLogger> cobalt_logger;

    inspect::UintProperty failed_to_open_device_count;
    inspect::UintProperty failed_to_obtain_fdio_service_channel_count;
    inspect::UintProperty failed_to_obtain_stream_channel_count;
    inspect::UintProperty failed_to_start_device_count;
    inspect::LinearIntHistogram mixer_clock_skew_discontinuities;
    inspect::Node outputs_node;
    inspect::Node inputs_node;
    inspect::Node renderers_node;
    inspect::Node capturers_node;
    inspect::Node thermal_state_transitions_node;
    inspect::Node volume_controls_node;

    std::unique_ptr<ThermalStateTracker> thermal_state_tracker;
    std::unique_ptr<ActiveUsagePolicyTracker> active_usage_policy_tracker;

    // These could be guarded by Reporter::mutex_, but clang's thread safety
    // analysis cannot represent that relationship.
    std::mutex mutex;
    uint64_t next_renderer_name FXL_GUARDED_BY(mutex) = 0;
    uint64_t next_capturer_name FXL_GUARDED_BY(mutex) = 0;
    uint64_t next_thermal_transition_name FXL_GUARDED_BY(mutex) = 0;
    uint64_t next_volume_control_name FXL_GUARDED_BY(mutex) = 0;

    Impl(sys::ComponentContext& cc, ThreadingModel& tm);
    ~Impl();

    std::string NextRendererName() {
      std::lock_guard<std::mutex> lock(mutex);
      return std::to_string(++next_renderer_name);
    }
    std::string NextCapturerName() {
      std::lock_guard<std::mutex> lock(mutex);
      return std::to_string(++next_capturer_name);
    }
    std::string NextThermalTransitionName() {
      std::lock_guard<std::mutex> lock(mutex);
      return std::to_string(++next_thermal_transition_name);
    }
    std::string NextVolumeControlName() {
      std::lock_guard<std::mutex> lock(mutex);
      return std::to_string(++next_volume_control_name);
    }
  };

  std::mutex mutex_;
  std::unique_ptr<Impl> impl_ FXL_GUARDED_BY(mutex_);

  // Caches of allocated objects so they can live beyond destruction.
  Container<OutputDevice, kObjectsToCache> outputs_;
  Container<InputDevice, kObjectsToCache> inputs_;
  Container<Renderer, kObjectsToCache> renderers_;
  Container<Capturer, kObjectsToCache> capturers_;
  Container<ThermalStateTransition, kThermalStatesToCache> thermal_state_transitions_;
  Container<VolumeControl, kVolumeControlsToCache> volume_controls_;
};

}  // namespace media::audio

#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_REPORTER_H_
