/*
 *  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/base/basictypes.h"
#include "webrtc/base/copyonwritebuffer.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"

namespace webrtc {
struct RTPHeader;
class RtpHeaderExtensionMap;
class Random;

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

  // Parse and copy given buffer into Packet.
  bool Parse(const uint8_t* buffer, size_t size);

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

  // Maps parsed extensions to their types to allow use of GetExtension.
  // Used after parsing when |extensions| can't be provided until base rtp
  // header is parsed.
  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;

  // TODO(danilchap): Remove this function when all code update to use RtpPacket
  // directly. Function is there just for easier backward compatibilty.
  void GetHeader(RTPHeader* header) const;

  size_t headers_size() const;

  // Payload.
  size_t payload_size() const;
  size_t padding_size() const;
  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();

  // Reserve size_bytes for payload. Returns nullptr on failure.
  uint8_t* AllocatePayload(size_t size_bytes);
  void SetPayloadSize(size_t size_bytes);
  bool SetPadding(uint8_t size_bytes, Random* random);

 protected:
  // |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.
  explicit Packet(const ExtensionManager* extensions);
  Packet(const Packet&) = default;
  Packet(const ExtensionManager* extensions, size_t capacity);
  virtual ~Packet();

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

 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 based on the type field of the parameter.
  // If found, length field would be validated, the offset field will be set
  // and true returned,
  // otherwise the parameter will be unchanged and false is returned.
  bool FindExtension(ExtensionType type,
                     uint8_t length,
                     uint16_t* offset) const;

  // Find or allocate an extension, based on the type field of the parameter.
  // If found, the length field be checked against what is already registered
  // and the offset field will be set, then true is returned. If allocated, the
  // length field will be used for allocation and the offset update to indicate
  // position, the true is returned.
  // If not found and allocations fails, false is returned and parameter remains
  // unchanged.
  bool AllocateExtension(ExtensionType type, uint8_t length, uint16_t* offset);

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

  const ExtensionManager* extensions_;

  // 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_;

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

  Packet() = delete;
};

template <typename Extension>
bool Packet::HasExtension() const {
  uint16_t offset = 0;
  return FindExtension(Extension::kId, Extension::kValueSizeBytes, &offset);
}

template <typename Extension, typename... Values>
bool Packet::GetExtension(Values... values) const {
  uint16_t offset = 0;
  if (!FindExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
    return false;
  return Extension::Parse(data() + offset, values...);
}

template <typename Extension, typename... Values>
bool Packet::SetExtension(Values... values) {
  uint16_t offset = 0;
  if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
    return false;
  return Extension::Write(WriteAt(offset), values...);
}

template <typename Extension>
bool Packet::ReserveExtension() {
  uint16_t offset = 0;
  if (!AllocateExtension(Extension::kId, Extension::kValueSizeBytes, &offset))
    return false;
  memset(WriteAt(offset), 0, Extension::kValueSizeBytes);
  return true;
}
}  // namespace rtp
}  // namespace webrtc

#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H_
