// 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_DEVICE_MANAGER_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_AUDIO_DEVICE_MANAGER_H_

#include <fbl/intrusive_double_list.h>
#include <fbl/ref_ptr.h>
#include <fuchsia/media/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/fit/function.h>

#include <set>

#include "lib/fidl/cpp/binding_set.h"
#include "src/media/audio/audio_core/audio_device.h"
#include "src/media/audio/audio_core/audio_input.h"
#include "src/media/audio/audio_core/audio_output.h"
#include "src/media/audio/audio_core/audio_plug_detector.h"
#include "src/media/audio/audio_core/fwd_decls.h"
#include "src/media/audio/audio_core/mixer/fx_loader.h"

namespace media::audio {

class AudioCapturerImpl;

class AudioDeviceManager : public ::fuchsia::media::AudioDeviceEnumerator {
 public:
  explicit AudioDeviceManager(AudioCoreImpl* service);
  ~AudioDeviceManager();

  // Initialize the output manager.  Called from the service implementation,
  // once, at startup time.  Should...
  //
  // 1) Initialize the mixing thread pool.
  // 2) Instantiate all of the built-in audio output devices.
  // 3) Monitor for plug/unplug events for pluggable audio output devices.
  // 4) Load the device effects library.
  zx_status_t Init();

  // Blocking call.  Called by the service, once, when it is time to shutdown
  // the service implementation.  While this function is blocking, it must never
  // block for long.  Our process is going away; this is our last chance to
  // perform a clean shutdown.  If an unclean shutdown must be performed in
  // order to implode in a timely fashion, so be it.
  //
  // Shutdown must be idempotent and safe to call from this object's destructor
  // (although this should never be necessary). If a shutdown called from this
  // destructor must do real work, something has gone Very Seriously Wrong.
  void Shutdown();

  // Add a new client for the device enumerator functionality.  Called from the
  // service framework each time a new client attempts to connect.
  void AddDeviceEnumeratorClient(
      fidl::InterfaceRequest<fuchsia::media::AudioDeviceEnumerator> request);

  // Add an AudioRenderer to the set of active AudioRenderers.
  void AddAudioRenderer(fbl::RefPtr<AudioRendererImpl> audio_renderer) {
    FXL_DCHECK(audio_renderer);
    audio_renderers_.push_back(std::move(audio_renderer));
  }

  // Remove an AudioRenderer from the set of active AudioRenderers.
  void RemoveAudioRenderer(AudioRendererImpl* audio_renderer) {
    FXL_DCHECK(audio_renderer != nullptr);
    FXL_DCHECK(audio_renderer->InContainer());
    audio_renderers_.erase(*audio_renderer);
  }

  // Select the initial set of outputs for a newly-configured AudioRenderer.
  void SelectOutputsForAudioRenderer(AudioRendererImpl* audio_renderer);

  // Link an output to an AudioRenderer.
  void LinkOutputToAudioRenderer(AudioOutput* output,
                                 AudioRendererImpl* audio_renderer);

  // Add/remove an AudioCapturer to/from the set of active AudioCapturers.
  void AddAudioCapturer(const fbl::RefPtr<AudioCapturerImpl>& audio_capturer);
  void RemoveAudioCapturer(AudioCapturerImpl* audio_capturer);

  // Schedule a closure to run on our encapsulating service's main message loop.
  void ScheduleMainThreadTask(fit::closure task);

  // Begin the process of initializing a device and add it to the set of device
  // which are waiting to be initialized.
  //
  // Called from the plug detector when a new stream device first shows up.
  zx_status_t AddDevice(const fbl::RefPtr<AudioDevice>& device);

  // Move a device from the pending init list to the active device's list.
  // Notify users of this new device, and re-evaluate policy decisions.
  void ActivateDevice(const fbl::RefPtr<AudioDevice>& device);

  // Shutdown this device; remove it from the appropriate set of active devices.
  void RemoveDevice(const fbl::RefPtr<AudioDevice>& device);

  // Handles a plugged/unplugged state change for the supplied audio device.
  void HandlePlugStateChange(const fbl::RefPtr<AudioDevice>& device,
                             bool plugged, zx_time_t plug_time);

  void SetRoutingPolicy(fuchsia::media::AudioOutputRoutingPolicy policy);

  static inline bool ValidateRoutingPolicy(
      fuchsia::media::AudioOutputRoutingPolicy policy) {
    switch (policy) {
      case fuchsia::media::AudioOutputRoutingPolicy::LAST_PLUGGED_OUTPUT:
      case fuchsia::media::AudioOutputRoutingPolicy::ALL_PLUGGED_OUTPUTS:
        return true;
        // Note: no default: handler here.  If someone adds a new policy to the
        // enum but forgets to update this code, we want a Build Break, to
        // notify us that we need to handle the new policy.
    }

    return false;
  }

  // SetSystemGain/Mute has been called. 'changed' tells us whether System Gain
  // or Mute values actually changed. If not, only update devices that (because
  // of calls to SetDeviceGain) have diverged from System settings.
  void OnSystemGain(bool changed);

  // Implementation of the AudioDeviceEnumerator FIDL interface.
  void GetDevices(GetDevicesCallback cbk) final;
  void GetDeviceGain(uint64_t device_token, GetDeviceGainCallback cbk) final;
  void SetDeviceGain(uint64_t device_token,
                     ::fuchsia::media::AudioGainInfo gain_info,
                     uint32_t set_flags) final;
  void GetDefaultInputDevice(GetDefaultInputDeviceCallback cbk) final;
  void GetDefaultOutputDevice(GetDefaultOutputDeviceCallback cbk) final;

  void EnableDeviceSettings(bool enabled) {
    AudioDeviceSettings::EnableDeviceSettings(enabled);
  }

 private:
  // KeyTraits we use to sort our AudioDeviceSettings set to ensure uniqueness.
  struct AudioDeviceSettingsKeyTraits {
    static const AudioDeviceSettings* GetKey(const AudioDeviceSettings& obj) {
      return &obj;
    }

    static bool LessThan(const AudioDeviceSettings* k1,
                         const AudioDeviceSettings* k2) {
      return (k1->is_input() && !k2->is_input()) ||
             ((k1->is_input() == k2->is_input()) &&
              (::memcmp(&k1->uid(), &k2->uid(), sizeof(k1->uid())) < 0));
    }

    static bool EqualTo(const AudioDeviceSettings* k1,
                        const AudioDeviceSettings* k2) {
      return (k1->is_input() == k2->is_input()) &&
             (::memcmp(&k1->uid(), &k2->uid(), sizeof(k1->uid())) == 0);
    }
  };

  using DeviceSettingsSet = fbl::WAVLTree<const AudioDeviceSettings*,
                                          fbl::RefPtr<AudioDeviceSettings>,
                                          AudioDeviceSettingsKeyTraits>;

  // Find the most-recently plugged device (per type: input or output) excluding
  // throttle_output. If allow_unplugged, return the most-recently UNplugged
  // device if no plugged devices are found -- otherwise return nullptr.
  fbl::RefPtr<AudioDevice> FindLastPlugged(AudioObject::Type type,
                                           bool allow_unplugged = false);

  fbl::RefPtr<AudioOutput> FindLastPluggedOutput(bool allow_unplugged = false) {
    auto dev = FindLastPlugged(AudioObject::Type::Output, allow_unplugged);
    FXL_DCHECK(!dev || (dev->type() == AudioObject::Type::Output));
    return fbl::RefPtr<AudioOutput>::Downcast(std::move(dev));
  }

  fbl::RefPtr<AudioInput> FindLastPluggedInput(bool allow_unplugged = false) {
    auto dev = FindLastPlugged(AudioObject::Type::Input, allow_unplugged);
    FXL_DCHECK(!dev || (dev->type() == AudioObject::Type::Input));
    return fbl::RefPtr<AudioInput>::Downcast(std::move(dev));
  }

  // Methods to handle routing policy -- when an existing device is unplugged or
  // completely removed, or when a new device is plugged or added to the system.
  void OnDeviceUnplugged(const fbl::RefPtr<AudioDevice>& device,
                         zx_time_t plug_time);
  void OnDevicePlugged(const fbl::RefPtr<AudioDevice>& device,
                       zx_time_t plug_time);

  void LinkToAudioCapturers(const fbl::RefPtr<AudioDevice>& device);

  // Commit any pending device-settings changes to disk (if settings are disk-
  // backed), then remove the settings from our persisted_device_settings_ map.
  void FinalizeDeviceSettings(const AudioDevice& device);

  // Send notification to users that this device's gain settings have changed.
  void NotifyDeviceGainChanged(const AudioDevice& device);

  // Re-evaluate which device is the default. Notify users, if this has changed.
  void UpdateDefaultDevice(bool input);

  // Update a device gain to the "system" gain exposed by the top-level service.
  //
  // TODO(johngro): Remove this when we remove system gain entirely.
  void UpdateDeviceToSystemGain(const fbl::RefPtr<AudioDevice>& device);

  // Commit any dirty settings to storage, (re)scheduling the timer as needed.
  void CommitDirtySettings();
  void CommitDirtySettingsThunk(async_dispatcher_t*, async::TaskBase*,
                                zx_status_t) {
    CommitDirtySettings();
  }

  // A pointer to the service which encapsulates us.  It is not possible for
  // this pointer to be bad while we still exist.
  AudioCoreImpl* service_;

  // The set of AudioDeviceEnumerator clients we are currently tending to.
  fidl::BindingSet<::fuchsia::media::AudioDeviceEnumerator> bindings_;

  // Our sets of currently active audio devices, AudioCapturers, and
  // AudioRenderers.
  //
  // Contents of these collections must only be manipulated on the main message
  // loop thread, so no synchronization should be needed.
  fbl::WAVLTree<uint64_t, fbl::RefPtr<AudioDevice>> devices_pending_init_;
  fbl::WAVLTree<uint64_t, fbl::RefPtr<AudioDevice>> devices_;
  fbl::DoublyLinkedList<fbl::RefPtr<AudioCapturerImpl>> audio_capturers_;
  fbl::DoublyLinkedList<fbl::RefPtr<AudioRendererImpl>> audio_renderers_;

  // The special throttle output always exists and is used by every renderer.
  fbl::RefPtr<AudioOutput> throttle_output_;

  // A helper class we will use to detect plug/unplug events for audio devices
  AudioPlugDetector plug_detector_;

  // State which affects routing policy.
  fuchsia::media::AudioOutputRoutingPolicy routing_policy_ =
      fuchsia::media::AudioOutputRoutingPolicy::LAST_PLUGGED_OUTPUT;
  uint64_t default_output_token_ = ZX_KOID_INVALID;
  uint64_t default_input_token_ = ZX_KOID_INVALID;

  // The unique AudioDeviceSettings subset we track that needs disk-persistence.
  DeviceSettingsSet persisted_device_settings_;
  async::TaskMethod<AudioDeviceManager,
                    &AudioDeviceManager::CommitDirtySettingsThunk>
      commit_settings_task_{this};

  FxLoader fx_loader_;
};

}  // namespace media::audio

#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_AUDIO_DEVICE_MANAGER_H_
