/*
 *  Copyright (c) 2017 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.
 */

#include "call/rtcp_demuxer.h"

#include <stddef.h>
#include <algorithm>
#include <utility>

#include "absl/types/optional.h"
#include "api/rtp_headers.h"
#include "call/rtcp_packet_sink_interface.h"
#include "call/rtp_rtcp_demuxer_helper.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "rtc_base/checks.h"

namespace webrtc {

RtcpDemuxer::RtcpDemuxer() = default;

RtcpDemuxer::~RtcpDemuxer() {
  RTC_DCHECK(ssrc_sinks_.empty());
  RTC_DCHECK(rsid_sinks_.empty());
  RTC_DCHECK(broadcast_sinks_.empty());
}

void RtcpDemuxer::AddSink(uint32_t sender_ssrc, RtcpPacketSinkInterface* sink) {
  RTC_DCHECK(sink);
  RTC_DCHECK(!ContainerHasKey(broadcast_sinks_, sink));
  RTC_DCHECK(!MultimapAssociationExists(ssrc_sinks_, sender_ssrc, sink));
  ssrc_sinks_.emplace(sender_ssrc, sink);
}

void RtcpDemuxer::AddSink(const std::string& rsid,
                          RtcpPacketSinkInterface* sink) {
  RTC_DCHECK(IsLegalRsidName(rsid));
  RTC_DCHECK(sink);
  RTC_DCHECK(!ContainerHasKey(broadcast_sinks_, sink));
  RTC_DCHECK(!MultimapAssociationExists(rsid_sinks_, rsid, sink));
  rsid_sinks_.emplace(rsid, sink);
}

void RtcpDemuxer::AddBroadcastSink(RtcpPacketSinkInterface* sink) {
  RTC_DCHECK(sink);
  RTC_DCHECK(!MultimapHasValue(ssrc_sinks_, sink));
  RTC_DCHECK(!MultimapHasValue(rsid_sinks_, sink));
  RTC_DCHECK(!ContainerHasKey(broadcast_sinks_, sink));
  broadcast_sinks_.push_back(sink);
}

void RtcpDemuxer::RemoveSink(const RtcpPacketSinkInterface* sink) {
  RTC_DCHECK(sink);
  size_t removal_count = RemoveFromMultimapByValue(&ssrc_sinks_, sink) +
                         RemoveFromMultimapByValue(&rsid_sinks_, sink);
  RTC_DCHECK_GT(removal_count, 0);
}

void RtcpDemuxer::RemoveBroadcastSink(const RtcpPacketSinkInterface* sink) {
  RTC_DCHECK(sink);
  auto it = std::find(broadcast_sinks_.begin(), broadcast_sinks_.end(), sink);
  RTC_DCHECK(it != broadcast_sinks_.end());
  broadcast_sinks_.erase(it);
}

void RtcpDemuxer::OnRtcpPacket(rtc::ArrayView<const uint8_t> packet) {
  // Perform sender-SSRC-based demuxing for packets with a sender-SSRC.
  absl::optional<uint32_t> sender_ssrc = ParseRtcpPacketSenderSsrc(packet);
  if (sender_ssrc) {
    auto it_range = ssrc_sinks_.equal_range(*sender_ssrc);
    for (auto it = it_range.first; it != it_range.second; ++it) {
      it->second->OnRtcpPacket(packet);
    }
  }

  // All packets, even those without a sender-SSRC, are broadcast to sinks
  // which listen to broadcasts.
  for (RtcpPacketSinkInterface* sink : broadcast_sinks_) {
    sink->OnRtcpPacket(packet);
  }
}

void RtcpDemuxer::OnSsrcBoundToRsid(const std::string& rsid, uint32_t ssrc) {
  // Record the new SSRC association for all of the sinks that were associated
  // with the RSID.
  auto it_range = rsid_sinks_.equal_range(rsid);
  for (auto it = it_range.first; it != it_range.second; ++it) {
    RtcpPacketSinkInterface* sink = it->second;
    // Watch out for pre-existing SSRC-based associations.
    if (!MultimapAssociationExists(ssrc_sinks_, ssrc, sink)) {
      AddSink(ssrc, sink);
    }
  }

  // RSIDs are uniquely associated with SSRCs; no need to keep in memory
  // the RSID-to-sink association of resolved RSIDs.
  rsid_sinks_.erase(it_range.first, it_range.second);
}

}  // namespace webrtc
