// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/base/bit_reader.h"

#include <stddef.h>
#include <stdint.h>

#include "base/cxx17_backports.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

static void SetBit(uint8_t* buf, size_t size, size_t bit_pos) {
  size_t byte_pos = bit_pos / 8;
  bit_pos -= byte_pos * 8;
  DCHECK_LT(byte_pos, size);
  buf[byte_pos] |= (1 << (7 - bit_pos));
}

TEST(BitReaderTest, NormalOperationTest) {
  uint8_t value8;
  uint64_t value64;
  // 0101 0101 1001 1001 repeats 4 times
  uint8_t buffer[] = {0x55, 0x99, 0x55, 0x99, 0x55, 0x99, 0x55, 0x99};
  BitReader reader1(buffer, 6);  // Initialize with 6 bytes only

  EXPECT_TRUE(reader1.ReadBits(1, &value8));
  EXPECT_EQ(value8, 0);
  EXPECT_TRUE(reader1.ReadBits(8, &value8));
  EXPECT_EQ(value8, 0xab);  // 1010 1011
  EXPECT_TRUE(reader1.ReadBits(7, &value64));
  EXPECT_TRUE(reader1.ReadBits(32, &value64));
  EXPECT_EQ(value64, 0x55995599u);
  EXPECT_FALSE(reader1.ReadBits(1, &value8));
  value8 = 0xff;
  EXPECT_TRUE(reader1.ReadBits(0, &value8));
  EXPECT_EQ(value8, 0);

  BitReader reader2(buffer, 8);
  EXPECT_TRUE(reader2.ReadBits(64, &value64));
  EXPECT_EQ(value64, 0x5599559955995599ull);
  EXPECT_FALSE(reader2.ReadBits(1, &value8));
  EXPECT_TRUE(reader2.ReadBits(0, &value8));
}

TEST(BitReaderTest, ReadBeyondEndTest) {
  uint8_t value8;
  uint8_t buffer[] = {0x12};
  BitReader reader1(buffer, sizeof(buffer));

  EXPECT_TRUE(reader1.ReadBits(4, &value8));
  EXPECT_FALSE(reader1.ReadBits(5, &value8));
  EXPECT_FALSE(reader1.ReadBits(1, &value8));
  EXPECT_TRUE(reader1.ReadBits(0, &value8));
}

TEST(BitReaderTest, SkipBitsTest) {
  uint8_t value8;
  uint8_t buffer[] = {0x0a, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  BitReader reader1(buffer, sizeof(buffer));

  EXPECT_TRUE(reader1.SkipBits(2));
  EXPECT_TRUE(reader1.ReadBits(3, &value8));
  EXPECT_EQ(value8, 1);
  EXPECT_TRUE(reader1.SkipBits(11));
  EXPECT_TRUE(reader1.ReadBits(8, &value8));
  EXPECT_EQ(value8, 3);
  EXPECT_TRUE(reader1.SkipBits(76));
  EXPECT_TRUE(reader1.ReadBits(4, &value8));
  EXPECT_EQ(value8, 13);
  EXPECT_FALSE(reader1.SkipBits(100));
  EXPECT_TRUE(reader1.SkipBits(0));
  EXPECT_FALSE(reader1.SkipBits(1));
}

TEST(BitReaderTest, VariableSkipBitsTest) {
  uint8_t buffer[256] = {0};

  // The test alternates between ReadBits and SkipBits.
  // The first number is the number of bits to read, the second one is the
  // number of bits to skip. The number of bits to read was arbitrarily chosen
  // while the number of bits to skip was chosen so as to cover from small skips
  // to large skips.
  const size_t pattern_read_skip[][2] = {
    {  5,  17 },
    {  4,  34 },
    {  0,  44 },
    {  3,   4 },   // Note: aligned read.
    {  7,   7 },   // Note: both read&skip cross byte boundary.
    { 17,  68 },
    {  7, 102 },
    {  9, 204 },
    {  3, 408 } };

  // Set bits to one only for the first and last bit of each read
  // in the pattern.
  size_t pos = 0;
  for (size_t k = 0; k < base::size(pattern_read_skip); ++k) {
    const size_t read_bit_count = pattern_read_skip[k][0];
    if (read_bit_count > 0) {
      SetBit(buffer, sizeof(buffer), pos);
      SetBit(buffer, sizeof(buffer), pos + read_bit_count - 1);
      pos += read_bit_count;
    }
    pos += pattern_read_skip[k][1];
  }

  // Run the test.
  BitReader bit_reader(buffer, sizeof(buffer));
  EXPECT_EQ(bit_reader.bits_available(), static_cast<int>(sizeof(buffer) * 8));
  for (size_t k = 0; k < base::size(pattern_read_skip); ++k) {
    const size_t read_bit_count = pattern_read_skip[k][0];
    if (read_bit_count > 0) {
      int value;
      EXPECT_TRUE(bit_reader.ReadBits(read_bit_count, &value));
      EXPECT_EQ(value, 1 | (1 << (read_bit_count - 1)));
    }
    EXPECT_TRUE(bit_reader.SkipBits(pattern_read_skip[k][1]));
  }
}

TEST(BitReaderTest, BitsReadTest) {
  int value;
  bool flag;
  uint8_t buffer[] = {0x0a, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  BitReader reader1(buffer, sizeof(buffer));
  EXPECT_EQ(reader1.bits_available(), 120);

  EXPECT_TRUE(reader1.SkipBits(2));
  EXPECT_EQ(reader1.bits_read(), 2);
  EXPECT_EQ(reader1.bits_available(), 118);
  EXPECT_TRUE(reader1.ReadBits(3, &value));
  EXPECT_EQ(reader1.bits_read(), 5);
  EXPECT_EQ(reader1.bits_available(), 115);
  EXPECT_TRUE(reader1.ReadFlag(&flag));
  EXPECT_EQ(reader1.bits_read(), 6);
  EXPECT_EQ(reader1.bits_available(), 114);
  EXPECT_TRUE(reader1.SkipBits(76));
  EXPECT_EQ(reader1.bits_read(), 82);
  EXPECT_EQ(reader1.bits_available(), 38);
}

}  // namespace media
