/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef CALL_BITRATE_ALLOCATOR_H_
#define CALL_BITRATE_ALLOCATOR_H_

#include <stdint.h>

#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "rtc_base/bitrateallocationstrategy.h"
#include "rtc_base/sequenced_task_checker.h"

namespace webrtc {

class Clock;

struct BitrateAllocationUpdate {
  // TODO(srte): Rename to target_bitrate.
  uint32_t bitrate_bps;
  uint32_t link_capacity_bps;
  uint8_t fraction_loss;
  int64_t rtt;
  int64_t bwe_period_ms;
};
// Used by all send streams with adaptive bitrate, to get the currently
// allocated bitrate for the send stream. The current network properties are
// given at the same time, to let the send stream decide about possible loss
// protection.
class BitrateAllocatorObserver {
 public:
  // Returns the amount of protection used by the BitrateAllocatorObserver
  // implementation, as bitrate in bps.
  virtual uint32_t OnBitrateUpdated(BitrateAllocationUpdate update) = 0;

 protected:
  virtual ~BitrateAllocatorObserver() {}
};

// Struct describing parameters for how a media stream should get bitrate
// allocated to it. |min_bitrate_bps| = 0 equals no min bitrate.
// |max_bitrate_bps| = 0 equals no max bitrate.
// |enforce_min_bitrate| = 'true' will allocate at least |min_bitrate_bps| for
//    this observer, even if the BWE is too low, 'false' will allocate 0 to
//    the observer if BWE doesn't allow |min_bitrate_bps|.
// |has_packet_feedback| indicates whether the data produced by the
// corresponding media stream will receive per packet feedback. This is
// tracked here to communicate to limit observers whether packet feedback can
// be expected, which is true if any of the active observers has packet
// feedback enabled. Note that |observer|->OnBitrateUpdated() will be called
// within the scope of this method with the current rtt, fraction_loss and
// available bitrate and that the bitrate in OnBitrateUpdated will be zero if
// the |observer| is currently not allowed to send data.
struct MediaStreamAllocationConfig {
  uint32_t min_bitrate_bps;
  uint32_t max_bitrate_bps;
  uint32_t pad_up_bitrate_bps;
  bool enforce_min_bitrate;
  std::string track_id;
  double bitrate_priority;
  bool has_packet_feedback;
};

// Interface used for mocking
class BitrateAllocatorInterface {
 public:
  virtual void AddObserver(BitrateAllocatorObserver* observer,
                           MediaStreamAllocationConfig config) = 0;
  virtual void RemoveObserver(BitrateAllocatorObserver* observer) = 0;
  virtual int GetStartBitrate(BitrateAllocatorObserver* observer) const = 0;

 protected:
  virtual ~BitrateAllocatorInterface() = default;
};

// Usage: this class will register multiple RtcpBitrateObserver's one at each
// RTCP module. It will aggregate the results and run one bandwidth estimation
// and push the result to the encoders via BitrateAllocatorObserver(s).
class BitrateAllocator : public BitrateAllocatorInterface {
 public:
  // Used to get notified when send stream limits such as the minimum send
  // bitrate and max padding bitrate is changed.
  class LimitObserver {
   public:
    virtual void OnAllocationLimitsChanged(
        uint32_t min_send_bitrate_bps,
        uint32_t max_padding_bitrate_bps,
        uint32_t total_bitrate_bps,
        uint32_t allocated_without_feedback_bps,
        bool has_packet_feedback) = 0;

   protected:
    virtual ~LimitObserver() = default;
  };

  explicit BitrateAllocator(LimitObserver* limit_observer);
  ~BitrateAllocator() override;

  // Allocate target_bitrate across the registered BitrateAllocatorObservers.
  void OnNetworkChanged(uint32_t target_bitrate_bps,
                        uint32_t link_capacity_bps,
                        uint8_t fraction_loss,
                        int64_t rtt,
                        int64_t bwe_period_ms);

  // Set the configuration used by the bandwidth management.
  // |observer| updates bitrates if already in use.
  // |config| is the configuration to use for allocation.
  void AddObserver(BitrateAllocatorObserver* observer,
                   MediaStreamAllocationConfig config) override;

  // Removes a previously added observer, but will not trigger a new bitrate
  // allocation.
  void RemoveObserver(BitrateAllocatorObserver* observer) override;

  // Returns initial bitrate allocated for |observer|. If |observer| is not in
  // the list of added observers, a best guess is returned.
  int GetStartBitrate(BitrateAllocatorObserver* observer) const override;

  // Sets external allocation strategy. If strategy is not set default WebRTC
  // allocation mechanism will be used. The strategy may be changed during call.
  // Setting NULL value will restore default WEBRTC allocation strategy.
  void SetBitrateAllocationStrategy(
      std::unique_ptr<rtc::BitrateAllocationStrategy>
          bitrate_allocation_strategy);

 private:
  struct ObserverConfig : rtc::BitrateAllocationStrategy::TrackConfig {
    ObserverConfig(BitrateAllocatorObserver* observer,
                   uint32_t min_bitrate_bps,
                   uint32_t max_bitrate_bps,
                   uint32_t pad_up_bitrate_bps,
                   bool enforce_min_bitrate,
                   std::string track_id,
                   double bitrate_priority,
                   bool has_packet_feedback)
        : TrackConfig(min_bitrate_bps,
                      max_bitrate_bps,
                      enforce_min_bitrate,
                      track_id),
          observer(observer),
          pad_up_bitrate_bps(pad_up_bitrate_bps),
          allocated_bitrate_bps(-1),
          media_ratio(1.0),
          bitrate_priority(bitrate_priority),
          has_packet_feedback(has_packet_feedback) {}

    BitrateAllocatorObserver* observer;
    uint32_t pad_up_bitrate_bps;
    int64_t allocated_bitrate_bps;
    double media_ratio;  // Part of the total bitrate used for media [0.0, 1.0].
    // The amount of bitrate allocated to this observer relative to all other
    // observers. If an observer has twice the bitrate_priority of other
    // observers, it should be allocated twice the bitrate above its min.
    double bitrate_priority;
    bool has_packet_feedback;

    uint32_t LastAllocatedBitrate() const;
    // The minimum bitrate required by this observer, including
    // enable-hysteresis if the observer is in a paused state.
    uint32_t MinBitrateWithHysteresis() const;
  };

  // Calculates the minimum requested send bitrate and max padding bitrate and
  // calls LimitObserver::OnAllocationLimitsChanged.
  void UpdateAllocationLimits() RTC_RUN_ON(&sequenced_checker_);

  typedef std::vector<ObserverConfig> ObserverConfigs;
  ObserverConfigs::const_iterator FindObserverConfig(
      const BitrateAllocatorObserver* observer) const
      RTC_RUN_ON(&sequenced_checker_);
  ObserverConfigs::iterator FindObserverConfig(
      const BitrateAllocatorObserver* observer) RTC_RUN_ON(&sequenced_checker_);

  typedef std::multimap<uint32_t, const ObserverConfig*> ObserverSortingMap;
  typedef std::map<BitrateAllocatorObserver*, int> ObserverAllocation;

  ObserverAllocation AllocateBitrates(uint32_t bitrate) const
      RTC_RUN_ON(&sequenced_checker_);

  // Allocates zero bitrate to all observers.
  ObserverAllocation ZeroRateAllocation() const RTC_RUN_ON(&sequenced_checker_);
  // Allocates bitrate to observers when there isn't enough to allocate the
  // minimum to all observers.
  ObserverAllocation LowRateAllocation(uint32_t bitrate) const
      RTC_RUN_ON(&sequenced_checker_);
  // Allocates bitrate to all observers when the available bandwidth is enough
  // to allocate the minimum to all observers but not enough to allocate the
  // max bitrate of each observer.
  ObserverAllocation NormalRateAllocation(uint32_t bitrate,
                                          uint32_t sum_min_bitrates) const
      RTC_RUN_ON(&sequenced_checker_);
  // Allocates bitrate to observers when there is enough available bandwidth
  // for all observers to be allocated their max bitrate.
  ObserverAllocation MaxRateAllocation(uint32_t bitrate,
                                       uint32_t sum_max_bitrates) const
      RTC_RUN_ON(&sequenced_checker_);

  // Splits |bitrate| evenly to observers already in |allocation|.
  // |include_zero_allocations| decides if zero allocations should be part of
  // the distribution or not. The allowed max bitrate is |max_multiplier| x
  // observer max bitrate.
  void DistributeBitrateEvenly(uint32_t bitrate,
                               bool include_zero_allocations,
                               int max_multiplier,
                               ObserverAllocation* allocation) const
      RTC_RUN_ON(&sequenced_checker_);
  bool EnoughBitrateForAllObservers(uint32_t bitrate,
                                    uint32_t sum_min_bitrates) const
      RTC_RUN_ON(&sequenced_checker_);

  // From the available |bitrate|, each observer will be allocated a
  // proportional amount based upon its bitrate priority. If that amount is
  // more than the observer's capacity, it will be allocated its capacity, and
  // the excess bitrate is still allocated proportionally to other observers.
  // Allocating the proportional amount means an observer with twice the
  // bitrate_priority of another will be allocated twice the bitrate.
  void DistributeBitrateRelatively(
      uint32_t bitrate,
      const ObserverAllocation& observers_capacities,
      ObserverAllocation* allocation) const RTC_RUN_ON(&sequenced_checker_);

  // Allow packets to be transmitted in up to 2 times max video bitrate if the
  // bandwidth estimate allows it.
  // TODO(bugs.webrtc.org/8541): May be worth to refactor to keep this logic in
  // video send stream. Similar logic is implemented in
  // AudioPriorityBitrateAllocationStrategy.
  static uint8_t GetTransmissionMaxBitrateMultiplier();

  rtc::SequencedTaskChecker sequenced_checker_;
  LimitObserver* const limit_observer_ RTC_GUARDED_BY(&sequenced_checker_);
  // Stored in a list to keep track of the insertion order.
  ObserverConfigs bitrate_observer_configs_ RTC_GUARDED_BY(&sequenced_checker_);
  uint32_t last_target_bps_ RTC_GUARDED_BY(&sequenced_checker_);
  uint32_t last_link_capacity_bps_ RTC_GUARDED_BY(&sequenced_checker_);
  uint32_t last_non_zero_bitrate_bps_ RTC_GUARDED_BY(&sequenced_checker_);
  uint8_t last_fraction_loss_ RTC_GUARDED_BY(&sequenced_checker_);
  int64_t last_rtt_ RTC_GUARDED_BY(&sequenced_checker_);
  int64_t last_bwe_period_ms_ RTC_GUARDED_BY(&sequenced_checker_);
  // Number of mute events based on too low BWE, not network up/down.
  int num_pause_events_ RTC_GUARDED_BY(&sequenced_checker_);
  Clock* const clock_ RTC_GUARDED_BY(&sequenced_checker_);
  int64_t last_bwe_log_time_ RTC_GUARDED_BY(&sequenced_checker_);
  uint32_t total_requested_padding_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
  uint32_t total_requested_min_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
  uint32_t total_requested_max_bitrate_ RTC_GUARDED_BY(&sequenced_checker_);
  uint32_t allocated_without_feedback_ RTC_GUARDED_BY(&sequenced_checker_);
  bool has_packet_feedback_ RTC_GUARDED_BY(&sequenced_checker_);
  std::unique_ptr<rtc::BitrateAllocationStrategy> bitrate_allocation_strategy_
      RTC_GUARDED_BY(&sequenced_checker_);
  const uint8_t transmission_max_bitrate_multiplier_;
};

}  // namespace webrtc
#endif  // CALL_BITRATE_ALLOCATOR_H_
