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

#include "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
