// 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_ROUTE_GRAPH_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_ROUTE_GRAPH_H_

#include <fuchsia/media/cpp/fidl.h>
#include <lib/fpromise/bridge.h>

#include <array>
#include <deque>
#include <unordered_map>

#include <fbl/ref_ptr.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/device_config.h"
#include "src/media/audio/audio_core/device_registry.h"
#include "src/media/audio/audio_core/idle_policy.h"
#include "src/media/audio/audio_core/link_matrix.h"
#include "src/media/audio/audio_core/threading_model.h"

namespace media::audio {

// |RoutingProfile| informs the |RouteGraph| on how or whether it should establish links for a
// particular input or output to the mixer.
struct RoutingProfile {
  bool routable = false;
  StreamUsage usage = {};
};

// |RouteGraph| is responsible for managing connections between inputs and outputs of the mixer.
//
// |RouteGraph| owns user-level inputs and outputs (|AudioRenderer|s and |AudioCapturer|s).
//
// Renderers are routed by Usage to the most recently plugged output that supports their Usage.
//
// Capturers are routed to the most recently plugged device that supports their usage.
class RouteGraph : public DeviceRouter {
 public:
  // Constructs a graph from the given config and link matrix. Each parameter must outlive the
  // RouteGraph.
  RouteGraph(LinkMatrix* link_matrix);

  ~RouteGraph();

  // DeviceRouter implementation
  //
  void SetIdlePowerOptionsFromPolicy(AudioPolicy::IdlePowerOptions options) override {}

  // Adds an |AudioInput| or |AudioOutput| to the route graph. An audio input may be connected to
  // transmit samples to an |AudioCapturer|; an audio output receives samples from an
  // |AudioRenderer|.
  void AddDeviceToRoutes(AudioDevice* input) final;

  // Removes an |AudioInput| or |AudioOutput| from the route graph. Any connected |AudioCapturer|s
  // or |AudioRenderer|s will be rerouted.
  void RemoveDeviceFromRoutes(AudioDevice* input) final;

  //
  // TODO(fxbug.dev/13339): Remove throttle_output_.
  // Sets a throttle output which is linked to all AudioRenderers to throttle the rate at which we
  // return packets to clients.
  void SetThrottleOutput(ThreadingModel* threading_model,
                         std::shared_ptr<AudioOutput> throttle_output);

  // Returns a boolean indicating if a |device| is contained in the route graph.
  bool ContainsDevice(const AudioDevice* device);

  // Adds an |AudioRenderer| to the route graph. An |AudioRenderer| may be connected to
  // |AudioOutput|s.
  void AddRenderer(std::shared_ptr<AudioObject> renderer);

  // Sets the routing profile with which the route graph selects |AudioOutput|s for the
  // |AudioRenderer|.
  void SetRendererRoutingProfile(const AudioObject& renderer, RoutingProfile profile);

  void RemoveRenderer(const AudioObject& renderer);

  // Adds an |AudioCapturer| to the route graph. An |AudioCapturer| may be connected to
  // |AudioInput|s to receive samples from them.
  void AddCapturer(std::shared_ptr<AudioObject> capturer);

  // Sets the routing profile with which the route graph selects |AudioInput|s for the
  // |AudioCapturer|.
  void SetCapturerRoutingProfile(const AudioObject& capturer, RoutingProfile profile);

  void RemoveCapturer(const AudioObject& capturer);

  std::unordered_set<AudioDevice*> TargetsForRenderUsage(const RenderUsage& usage);

  std::shared_ptr<LoudnessTransform> LoudnessTransformForUsage(const StreamUsage& usage);

 private:
  struct RoutableOwnedObject {
    std::shared_ptr<AudioObject> ref;
    RoutingProfile profile;
  };

  struct Target {
    Target() = default;

    Target(AudioDevice* _device, std::shared_ptr<LoudnessTransform> _transform)
        : device(_device), transform(_transform) {
      FX_DCHECK(!!device == !!transform);
    }

    bool is_linkable() const { return device; }

    AudioDevice* device = nullptr;
    std::shared_ptr<LoudnessTransform> transform = nullptr;
  };
  using Targets = std::array<Target, kStreamUsageCount>;
  using UnlinkCommand = std::array<bool, kStreamUsageCount>;

  void UpdateGraphForDeviceChange();

  // Calculate the new targets based on our routing policy and available devices.
  // Returns the new targets and an unlink command to unlink any out of date
  // routing links.
  std::pair<Targets, UnlinkCommand> CalculateTargets() const;

  void Unlink(UnlinkCommand unlink_command);

  Target TargetForUsage(const StreamUsage& usage) const;

  LinkMatrix& link_matrix_;

  Targets targets_ = {};

  // TODO(fxbug.dev/39624): convert to weak_ptr when ownership is explicit.
  std::deque<AudioDevice*> devices_;

  std::unordered_map<const AudioObject*, RoutableOwnedObject> capturers_;
  std::unordered_map<const AudioObject*, RoutableOwnedObject> renderers_;
  std::unordered_map<const AudioObject*, RoutableOwnedObject> loopback_capturers_;

  // TODO(fxbug.dev/13339): Remove throttle_output_.
  std::optional<fpromise::completer<void, void>> throttle_release_fence_;
  std::shared_ptr<AudioOutput> throttle_output_;

  // For debugging purposes only
  void DisplayRenderers();
  void DisplayCapturers();
  void DisplayDevices();
};

}  // namespace media::audio

#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_ROUTE_GRAPH_H_
