/*
 *  Copyright (c) 2016 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 WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_

#include <vector>

#include "webrtc/api/array_view.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/rtc_base/basictypes.h"
#include "webrtc/rtc_base/copyonwritebuffer.h"

namespace webrtc {
class RtpHeaderExtensionMap;
class Random;

namespace rtp {
class Packet {
 public:
  using ExtensionType = RTPExtensionType;
  using ExtensionManager = RtpHeaderExtensionMap;
  static constexpr size_t kMaxExtensionHeaders = 14;
  static constexpr int kMinExtensionId = 1;
  static constexpr int kMaxExtensionId = 14;

  // |extensions| required for SetExtension/ReserveExtension functions during
  // packet creating and used if available in Parse function.
  // Adding and getting extensions will fail until |extensions| is
  // provided via constructor or IdentifyExtensions function.
  Packet();
  explicit Packet(const ExtensionManager* extensions);
  Packet(const Packet&);
  Packet(const ExtensionManager* extensions, size_t capacity);
  ~Packet();

  Packet& operator=(const Packet&) = default;

  // Parse and copy given buffer into Packet.
  bool Parse(const uint8_t* buffer, size_t size);
  bool Parse(rtc::ArrayView<const uint8_t> packet);

  // Parse and move given buffer into Packet.
  bool Parse(rtc::CopyOnWriteBuffer packet);

  // Maps extensions id to their types.
  void IdentifyExtensions(const ExtensionManager& extensions);

  // Header.
  bool Marker() const;
  uint8_t PayloadType() const;
  uint16_t SequenceNumber() const;
  uint32_t Timestamp() const;
  uint32_t Ssrc() const;
  std::vector<uint32_t> Csrcs() const;

  size_t headers_size() const;

  // Payload.
  size_t payload_size() const;
  size_t padding_size() const;
  rtc::ArrayView<const uint8_t> payload() const;

  // Buffer.
  rtc::CopyOnWriteBuffer Buffer() const;
  size_t capacity() const;
  size_t size() const;
  const uint8_t* data() const;
  size_t FreeCapacity() const;
  size_t MaxPayloadSize() const;

  // Reset fields and buffer.
  void Clear();

  // Header setters.
  void CopyHeaderFrom(const Packet& packet);
  void SetMarker(bool marker_bit);
  void SetPayloadType(uint8_t payload_type);
  void SetSequenceNumber(uint16_t seq_no);
  void SetTimestamp(uint32_t timestamp);
  void SetSsrc(uint32_t ssrc);

  // Writes csrc list. Assumes:
  // a) There is enough room left in buffer.
  // b) Extension headers, payload or padding data has not already been added.
  void SetCsrcs(const std::vector<uint32_t>& csrcs);

  // Header extensions.
  template <typename Extension>
  bool HasExtension() const;

  template <typename Extension, typename... Values>
  bool GetExtension(Values...) const;

  template <typename Extension, typename... Values>
  bool SetExtension(Values...);

  template <typename Extension>
  bool ReserveExtension();

  // Following 4 helpers identify rtp header extension by |id| negotiated with
  // remote peer and written in an rtp packet.
  bool HasRawExtension(int id) const;

  // Returns place where extension with |id| is stored.
  // Returns empty arrayview if extension is not present.
  rtc::ArrayView<const uint8_t> GetRawExtension(int id) const;

  // Allocates and store header extension. Returns true on success.
  bool SetRawExtension(int id, rtc::ArrayView<const uint8_t> data);

  // Allocates and returns place to store rtp header extension.
  // Returns empty arrayview on failure.
  rtc::ArrayView<uint8_t> AllocateRawExtension(int id, size_t length);

  // Reserve size_bytes for payload. Returns nullptr on failure.
  uint8_t* SetPayloadSize(size_t size_bytes);
  // Same as SetPayloadSize but doesn't guarantee to keep current payload.
  uint8_t* AllocatePayload(size_t size_bytes);
  bool SetPadding(uint8_t size_bytes, Random* random);

 private:
  struct ExtensionInfo {
    ExtensionType type;
    uint16_t offset;
    uint8_t length;
  };

  // Helper function for Parse. Fill header fields using data in given buffer,
  // but does not touch packet own buffer, leaving packet in invalid state.
  bool ParseBuffer(const uint8_t* buffer, size_t size);

  // Find an extension |type|.
  // Returns view of the raw extension or empty view on failure.
  rtc::ArrayView<const uint8_t> FindExtension(ExtensionType type) const;

  // Find or allocate an extension |type|. Returns view of size |length|
  // to write raw extension to or an empty view on failure.
  rtc::ArrayView<uint8_t> AllocateExtension(ExtensionType type, size_t length);

  uint8_t* WriteAt(size_t offset);
  void WriteAt(size_t offset, uint8_t byte);

  // Header.
  bool marker_;
  uint8_t payload_type_;
  uint8_t padding_size_;
  uint16_t sequence_number_;
  uint32_t timestamp_;
  uint32_t ssrc_;
  size_t payload_offset_;  // Match header size with csrcs and extensions.
  size_t payload_size_;

  ExtensionInfo extension_entries_[kMaxExtensionHeaders];
  uint16_t extensions_size_ = 0;  // Unaligned.
  rtc::CopyOnWriteBuffer buffer_;
};

template <typename Extension>
bool Packet::HasExtension() const {
  return !FindExtension(Extension::kId).empty();
}

template <typename Extension, typename... Values>
bool Packet::GetExtension(Values... values) const {
  auto raw = FindExtension(Extension::kId);
  if (raw.empty())
    return false;
  return Extension::Parse(raw, values...);
}

template <typename Extension, typename... Values>
bool Packet::SetExtension(Values... values) {
  const size_t value_size = Extension::ValueSize(values...);
  if (value_size == 0 || value_size > 16)
    return false;
  auto buffer = AllocateExtension(Extension::kId, value_size);
  if (buffer.empty())
    return false;
  return Extension::Write(buffer.data(), values...);
}

template <typename Extension>
bool Packet::ReserveExtension() {
  auto buffer = AllocateExtension(Extension::kId, Extension::kValueSizeBytes);
  if (buffer.empty())
    return false;
  memset(buffer.data(), 0, Extension::kValueSizeBytes);
  return true;
}
}  // namespace rtp
}  // namespace webrtc

#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_
