/*
 *  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
