// 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 "cobalt/media/base/data_buffer.h"

#include <memory>
#include <utility>

#include "base/basictypes.h"
#include "base/strings/string_util.h"
#include "starboard/memory.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace media {

TEST(DataBufferTest, Constructor_ZeroSize) {
  // Zero-sized buffers are valid. In practice they aren't used very much but it
  // eliminates clients from worrying about null data pointers.
  scoped_refptr<DataBuffer> buffer = new DataBuffer(0);
  EXPECT_TRUE(buffer->data());
  EXPECT_TRUE(buffer->writable_data());
  EXPECT_EQ(0, buffer->data_size());
  EXPECT_FALSE(buffer->end_of_stream());
}

TEST(DataBufferTest, Constructor_NonZeroSize) {
  // Buffer size should be set.
  scoped_refptr<DataBuffer> buffer = new DataBuffer(10);
  EXPECT_TRUE(buffer->data());
  EXPECT_TRUE(buffer->writable_data());
  EXPECT_EQ(0, buffer->data_size());
  EXPECT_FALSE(buffer->end_of_stream());
}

TEST(DataBufferTest, Constructor_ScopedArray) {
  // Data should be passed and both data and buffer size should be set.
  const int kSize = 8;
  std::unique_ptr<uint8_t[]> data(new uint8_t[kSize]);
  const uint8_t* kData = data.get();

  scoped_refptr<DataBuffer> buffer = new DataBuffer(std::move(data), kSize);
  EXPECT_TRUE(buffer->data());
  EXPECT_TRUE(buffer->writable_data());
  EXPECT_EQ(kData, buffer->data());
  EXPECT_EQ(kSize, buffer->data_size());
  EXPECT_FALSE(buffer->end_of_stream());
}

TEST(DataBufferTest, CopyFrom) {
  const uint8_t kTestData[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
  const int kTestDataSize = arraysize(kTestData);

  scoped_refptr<DataBuffer> buffer =
      DataBuffer::CopyFrom(kTestData, kTestDataSize);
  EXPECT_EQ(kTestDataSize, buffer->data_size());
  EXPECT_FALSE(buffer->end_of_stream());

  // Ensure we are copying the data, not just pointing to the original data.
  EXPECT_EQ(0, SbMemoryCompare(buffer->data(), kTestData, kTestDataSize));
  buffer->writable_data()[0] = 0xFF;
  EXPECT_NE(0, SbMemoryCompare(buffer->data(), kTestData, kTestDataSize));
}

TEST(DataBufferTest, CreateEOSBuffer) {
  scoped_refptr<DataBuffer> buffer = DataBuffer::CreateEOSBuffer();
  EXPECT_TRUE(buffer->end_of_stream());
}

TEST(DataBufferTest, Timestamp) {
  const base::TimeDelta kZero;
  const base::TimeDelta kTimestampA = base::TimeDelta::FromMicroseconds(1337);
  const base::TimeDelta kTimestampB = base::TimeDelta::FromMicroseconds(1234);

  scoped_refptr<DataBuffer> buffer = new DataBuffer(0);
  EXPECT_TRUE(buffer->timestamp() == kZero);

  buffer->set_timestamp(kTimestampA);
  EXPECT_TRUE(buffer->timestamp() == kTimestampA);

  buffer->set_timestamp(kTimestampB);
  EXPECT_TRUE(buffer->timestamp() == kTimestampB);
}

TEST(DataBufferTest, Duration) {
  const base::TimeDelta kZero;
  const base::TimeDelta kDurationA = base::TimeDelta::FromMicroseconds(1337);
  const base::TimeDelta kDurationB = base::TimeDelta::FromMicroseconds(1234);

  scoped_refptr<DataBuffer> buffer = new DataBuffer(0);
  EXPECT_TRUE(buffer->duration() == kZero);

  buffer->set_duration(kDurationA);
  EXPECT_TRUE(buffer->duration() == kDurationA);

  buffer->set_duration(kDurationB);
  EXPECT_TRUE(buffer->duration() == kDurationB);
}

TEST(DataBufferTest, ReadingWriting) {
  const char kData[] = "hello";
  const int kDataSize = arraysize(kData);
  const char kNewData[] = "chromium";
  const int kNewDataSize = arraysize(kNewData);

  // Create a DataBuffer.
  scoped_refptr<DataBuffer> buffer(new DataBuffer(kDataSize));
  ASSERT_TRUE(buffer.get());

  uint8_t* data = buffer->writable_data();
  ASSERT_TRUE(data);
  SbMemoryCopy(data, kData, kDataSize);
  buffer->set_data_size(kDataSize);
  const uint8_t* read_only_data = buffer->data();
  ASSERT_EQ(data, read_only_data);
  ASSERT_EQ(0, SbMemoryCompare(read_only_data, kData, kDataSize));
  EXPECT_FALSE(buffer->end_of_stream());

  scoped_refptr<DataBuffer> buffer2(new DataBuffer(kNewDataSize + 10));
  data = buffer2->writable_data();
  ASSERT_TRUE(data);
  SbMemoryCopy(data, kNewData, kNewDataSize);
  buffer2->set_data_size(kNewDataSize);
  read_only_data = buffer2->data();
  EXPECT_EQ(kNewDataSize, buffer2->data_size());
  ASSERT_EQ(data, read_only_data);
  EXPECT_EQ(0, SbMemoryCompare(read_only_data, kNewData, kNewDataSize));
}

}  // namespace media
}  // namespace cobalt
