/*
 *  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/source/rtp_format_vp8_test_helper.h"

#include "webrtc/test/gtest.h"

namespace webrtc {

namespace test {

constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr;

RtpFormatVp8TestHelper::RtpFormatVp8TestHelper(const RTPVideoHeaderVP8* hdr)
    : packet_(kNoExtensions),
      payload_data_(NULL),
      data_ptr_(NULL),
      fragmentation_(NULL),
      hdr_info_(hdr),
      payload_start_(0),
      payload_size_(0),
      sloppy_partitioning_(false),
      inited_(false) {}

RtpFormatVp8TestHelper::~RtpFormatVp8TestHelper() {
  delete fragmentation_;
  delete [] payload_data_;
}

bool RtpFormatVp8TestHelper::Init(const size_t* partition_sizes,
                                  size_t num_partitions) {
  if (inited_) return false;
  fragmentation_ = new RTPFragmentationHeader;
  fragmentation_->VerifyAndAllocateFragmentationHeader(num_partitions);
  payload_size_ = 0;
  // Calculate sum payload size.
  for (size_t p = 0; p < num_partitions; ++p) {
    payload_size_ += partition_sizes[p];
  }
  payload_data_ = new uint8_t[payload_size_];
  size_t j = 0;
  // Loop through the partitions again.
  for (size_t p = 0; p < num_partitions; ++p) {
    fragmentation_->fragmentationLength[p] = partition_sizes[p];
    fragmentation_->fragmentationOffset[p] = j;
    for (size_t i = 0; i < partition_sizes[p]; ++i) {
      assert(j < payload_size_);
      payload_data_[j++] = p;  // Set the payload value to the partition index.
    }
  }
  data_ptr_ = payload_data_;
  inited_ = true;
  return true;
}

void RtpFormatVp8TestHelper::GetAllPacketsAndCheck(
    RtpPacketizerVp8* packetizer,
    const size_t* expected_sizes,
    const int* expected_part,
    const bool* expected_frag_start,
    size_t expected_num_packets) {
  ASSERT_TRUE(inited_);
  for (size_t i = 0; i < expected_num_packets; ++i) {
    std::ostringstream ss;
    ss << "Checking packet " << i;
    SCOPED_TRACE(ss.str());
    EXPECT_TRUE(packetizer->NextPacket(&packet_));
    CheckPacket(expected_sizes[i], i + 1 == expected_num_packets,
                expected_frag_start[i]);
  }
}

// Payload descriptor
//       0 1 2 3 4 5 6 7
//      +-+-+-+-+-+-+-+-+
//      |X|R|N|S|PartID | (REQUIRED)
//      +-+-+-+-+-+-+-+-+
// X:   |I|L|T|K|  RSV  | (OPTIONAL)
//      +-+-+-+-+-+-+-+-+
// I:   |   PictureID   | (OPTIONAL)
//      +-+-+-+-+-+-+-+-+
// L:   |   TL0PICIDX   | (OPTIONAL)
//      +-+-+-+-+-+-+-+-+
// T/K: | TID | KEYIDX  | (OPTIONAL)
//      +-+-+-+-+-+-+-+-+

// First octet tests.
#define EXPECT_BIT_EQ(x, n, a) EXPECT_EQ((((x) >> (n)) & 0x1), a)

#define EXPECT_RSV_ZERO(x) EXPECT_EQ(((x) & 0xE0), 0)

#define EXPECT_BIT_X_EQ(x, a) EXPECT_BIT_EQ(x, 7, a)

#define EXPECT_BIT_N_EQ(x, a) EXPECT_BIT_EQ(x, 5, a)

#define EXPECT_BIT_S_EQ(x, a) EXPECT_BIT_EQ(x, 4, a)

#define EXPECT_PART_ID_EQ(x, a) EXPECT_EQ(((x) & 0x0F), a)

// Extension fields tests
#define EXPECT_BIT_I_EQ(x, a) EXPECT_BIT_EQ(x, 7, a)

#define EXPECT_BIT_L_EQ(x, a) EXPECT_BIT_EQ(x, 6, a)

#define EXPECT_BIT_T_EQ(x, a) EXPECT_BIT_EQ(x, 5, a)

#define EXPECT_BIT_K_EQ(x, a) EXPECT_BIT_EQ(x, 4, a)

#define EXPECT_TID_EQ(x, a) EXPECT_EQ((((x) & 0xC0) >> 6), a)

#define EXPECT_BIT_Y_EQ(x, a) EXPECT_BIT_EQ(x, 5, a)

#define EXPECT_KEYIDX_EQ(x, a) EXPECT_EQ(((x) & 0x1F), a)

void RtpFormatVp8TestHelper::CheckHeader(bool frag_start) {
  payload_start_ = 1;
  rtc::ArrayView<const uint8_t> buffer = packet_.payload();
  EXPECT_BIT_EQ(buffer[0], 6, 0);  // Check reserved bit.

  if (hdr_info_->pictureId != kNoPictureId ||
      hdr_info_->temporalIdx != kNoTemporalIdx ||
      hdr_info_->tl0PicIdx != kNoTl0PicIdx ||
      hdr_info_->keyIdx != kNoKeyIdx) {
    EXPECT_BIT_X_EQ(buffer[0], 1);
    ++payload_start_;
    CheckPictureID();
    CheckTl0PicIdx();
    CheckTIDAndKeyIdx();
  } else {
    EXPECT_BIT_X_EQ(buffer[0], 0);
  }

  EXPECT_BIT_N_EQ(buffer[0], hdr_info_->nonReference ? 1 : 0);
  EXPECT_BIT_S_EQ(buffer[0], frag_start ? 1 : 0);

  // Check partition index.
  if (!sloppy_partitioning_) {
    // The test payload data is constructed such that the payload value is the
    // same as the partition index.
    EXPECT_EQ(buffer[0] & 0x0F, buffer[payload_start_]);
  } else {
    // Partition should be set to 0.
    EXPECT_EQ(buffer[0] & 0x0F, 0);
  }
}

// Verify that the I bit and the PictureID field are both set in accordance
// with the information in hdr_info_->pictureId.
void RtpFormatVp8TestHelper::CheckPictureID() {
  auto buffer = packet_.payload();
  if (hdr_info_->pictureId != kNoPictureId) {
    EXPECT_BIT_I_EQ(buffer[1], 1);
    EXPECT_BIT_EQ(buffer[payload_start_], 7, 1);
    EXPECT_EQ(buffer[payload_start_] & 0x7F,
              (hdr_info_->pictureId >> 8) & 0x7F);
    EXPECT_EQ(buffer[payload_start_ + 1], hdr_info_->pictureId & 0xFF);
    payload_start_ += 2;
  } else {
    EXPECT_BIT_I_EQ(buffer[1], 0);
  }
}

// Verify that the L bit and the TL0PICIDX field are both set in accordance
// with the information in hdr_info_->tl0PicIdx.
void RtpFormatVp8TestHelper::CheckTl0PicIdx() {
  auto buffer = packet_.payload();
  if (hdr_info_->tl0PicIdx != kNoTl0PicIdx) {
    EXPECT_BIT_L_EQ(buffer[1], 1);
    EXPECT_EQ(buffer[payload_start_], hdr_info_->tl0PicIdx);
    ++payload_start_;
  } else {
    EXPECT_BIT_L_EQ(buffer[1], 0);
  }
}

// Verify that the T bit and the TL0PICIDX field, and the K bit and KEYIDX
// field are all set in accordance with the information in
// hdr_info_->temporalIdx and hdr_info_->keyIdx, respectively.
void RtpFormatVp8TestHelper::CheckTIDAndKeyIdx() {
  auto buffer = packet_.payload();
  if (hdr_info_->temporalIdx == kNoTemporalIdx &&
      hdr_info_->keyIdx == kNoKeyIdx) {
    EXPECT_BIT_T_EQ(buffer[1], 0);
    EXPECT_BIT_K_EQ(buffer[1], 0);
    return;
  }
  if (hdr_info_->temporalIdx != kNoTemporalIdx) {
    EXPECT_BIT_T_EQ(buffer[1], 1);
    EXPECT_TID_EQ(buffer[payload_start_], hdr_info_->temporalIdx);
    EXPECT_BIT_Y_EQ(buffer[payload_start_], hdr_info_->layerSync ? 1 : 0);
  } else {
    EXPECT_BIT_T_EQ(buffer[1], 0);
    EXPECT_TID_EQ(buffer[payload_start_], 0);
    EXPECT_BIT_Y_EQ(buffer[payload_start_], 0);
  }
  if (hdr_info_->keyIdx != kNoKeyIdx) {
    EXPECT_BIT_K_EQ(buffer[1], 1);
    EXPECT_KEYIDX_EQ(buffer[payload_start_], hdr_info_->keyIdx);
  } else {
    EXPECT_BIT_K_EQ(buffer[1], 0);
    EXPECT_KEYIDX_EQ(buffer[payload_start_], 0);
  }
  ++payload_start_;
}

// Verify that the payload (i.e., after the headers) of the packet stored in
// buffer_ is identical to the expected (as found in data_ptr_).
void RtpFormatVp8TestHelper::CheckPayload() {
  auto buffer = packet_.payload();
  size_t payload_end = buffer.size();
  for (size_t i = payload_start_; i < payload_end; ++i, ++data_ptr_)
    EXPECT_EQ(buffer[i], *data_ptr_);
}

// Verify that the input variable "last" agrees with the position of data_ptr_.
// If data_ptr_ has advanced payload_size_ bytes from the start (payload_data_)
// we are at the end and last should be true. Otherwise, it should be false.
void RtpFormatVp8TestHelper::CheckLast(bool last) const {
  EXPECT_EQ(last, data_ptr_ == payload_data_ + payload_size_);
}

// Verify the contents of a packet. Check the length versus expected_bytes,
// the header, payload, and "last" flag.
void RtpFormatVp8TestHelper::CheckPacket(size_t expect_bytes,
                                         bool last,
                                         bool frag_start) {
  EXPECT_EQ(expect_bytes, packet_.payload_size());
  CheckHeader(frag_start);
  CheckPayload();
  CheckLast(last);
}

}  // namespace test

}  // namespace webrtc
