/*
 *  Copyright (c) 2012 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 "webrtc/modules/rtp_rtcp/include/rtp_header_extension_map.h"

#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "webrtc/rtc_base/arraysize.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/logging.h"

namespace webrtc {
namespace {

struct ExtensionInfo {
  RTPExtensionType type;
  const char* uri;
};

template <typename Extension>
constexpr ExtensionInfo CreateExtensionInfo() {
  return {Extension::kId, Extension::kUri};
}

constexpr ExtensionInfo kExtensions[] = {
    CreateExtensionInfo<TransmissionOffset>(),
    CreateExtensionInfo<AudioLevel>(),
    CreateExtensionInfo<AbsoluteSendTime>(),
    CreateExtensionInfo<VideoOrientation>(),
    CreateExtensionInfo<TransportSequenceNumber>(),
    CreateExtensionInfo<PlayoutDelayLimits>(),
    CreateExtensionInfo<VideoContentTypeExtension>(),
    CreateExtensionInfo<VideoTimingExtension>(),
    CreateExtensionInfo<RtpStreamId>(),
    CreateExtensionInfo<RepairedRtpStreamId>(),
    CreateExtensionInfo<RtpMid>(),
};

// Because of kRtpExtensionNone, NumberOfExtension is 1 bigger than the actual
// number of known extensions.
static_assert(arraysize(kExtensions) ==
                  static_cast<int>(kRtpExtensionNumberOfExtensions) - 1,
              "kExtensions expect to list all known extensions");

}  // namespace

constexpr RTPExtensionType RtpHeaderExtensionMap::kInvalidType;
constexpr uint8_t RtpHeaderExtensionMap::kInvalidId;
constexpr uint8_t RtpHeaderExtensionMap::kMinId;
constexpr uint8_t RtpHeaderExtensionMap::kMaxId;

RtpHeaderExtensionMap::RtpHeaderExtensionMap() {
  for (auto& type : types_)
    type = kInvalidType;
  for (auto& id : ids_)
    id = kInvalidId;
}

RtpHeaderExtensionMap::RtpHeaderExtensionMap(
    rtc::ArrayView<const RtpExtension> extensions)
    : RtpHeaderExtensionMap() {
  for (const RtpExtension& extension : extensions)
    RegisterByUri(extension.id, extension.uri);
}

bool RtpHeaderExtensionMap::RegisterByType(uint8_t id, RTPExtensionType type) {
  for (const ExtensionInfo& extension : kExtensions)
    if (type == extension.type)
      return Register(id, extension.type, extension.uri);
  RTC_NOTREACHED();
  return false;
}

bool RtpHeaderExtensionMap::RegisterByUri(uint8_t id, const std::string& uri) {
  for (const ExtensionInfo& extension : kExtensions)
    if (uri == extension.uri)
      return Register(id, extension.type, extension.uri);
  LOG(LS_WARNING) << "Unknown extension uri:'" << uri
                  << "', id: " << static_cast<int>(id) << '.';
  return false;
}

size_t RtpHeaderExtensionMap::GetTotalLengthInBytes(
    rtc::ArrayView<const RtpExtensionSize> extensions) const {
  // Header size of the extension block, see RFC3550 Section 5.3.1
  static constexpr size_t kRtpOneByteHeaderLength = 4;
  // Header size of each individual extension, see RFC5285 Section 4.2
  static constexpr size_t kExtensionHeaderLength = 1;
  size_t values_size = 0;
  for (const RtpExtensionSize& extension : extensions) {
    if (IsRegistered(extension.type))
      values_size += extension.value_size + kExtensionHeaderLength;
  }
  if (values_size == 0)
    return 0;
  size_t size = kRtpOneByteHeaderLength + values_size;
  // Round up to the nearest size that is a multiple of 4.
  // Which is same as round down (size + 3).
  return size + 3 - (size + 3) % 4;
}

int32_t RtpHeaderExtensionMap::Deregister(RTPExtensionType type) {
  if (IsRegistered(type)) {
    uint8_t id = GetId(type);
    types_[id] = kInvalidType;
    ids_[type] = kInvalidId;
  }
  return 0;
}

bool RtpHeaderExtensionMap::Register(uint8_t id,
                                     RTPExtensionType type,
                                     const char* uri) {
  RTC_DCHECK_GT(type, kRtpExtensionNone);
  RTC_DCHECK_LT(type, kRtpExtensionNumberOfExtensions);

  if (id < kMinId || id > kMaxId) {
    LOG(LS_WARNING) << "Failed to register extension uri:'" << uri
                    << "' with invalid id:" << static_cast<int>(id) << ".";
    return false;
  }

  if (GetType(id) == type) {  // Same type/id pair already registered.
    LOG(LS_VERBOSE) << "Reregistering extension uri:'" << uri
                    << "', id:" << static_cast<int>(id);
    return true;
  }

  if (GetType(id) != kInvalidType) {  // |id| used by another extension type.
    LOG(LS_WARNING) << "Failed to register extension uri:'" << uri
                    << "', id:" << static_cast<int>(id)
                    << ". Id already in use by extension type "
                    << static_cast<int>(GetType(id));
    return false;
  }
  RTC_DCHECK(!IsRegistered(type));

  types_[id] = type;
  ids_[type] = id;
  return true;
}

}  // namespace webrtc
