// 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/buffers.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decoder_buffer_queue.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

static base::TimeDelta ToTimeDelta(int seconds) {
  if (seconds < 0)
    return kNoTimestamp();
  return base::TimeDelta::FromSeconds(seconds);
}

// Helper to create buffers with specified timestamp in seconds.
//
// Negative numbers will be converted to kNoTimestamp();
static scoped_refptr<DecoderBuffer> CreateBuffer(int timestamp) {
  scoped_refptr<DecoderBuffer> buffer = new DecoderBuffer(0);
  buffer->set_timestamp(ToTimeDelta(timestamp));
  buffer->set_duration(ToTimeDelta(0));
  return buffer;
}

static scoped_refptr<DecoderBuffer> CreateBuffer(int timestamp, int size) {
  scoped_refptr<DecoderBuffer> buffer = new DecoderBuffer(size);
  buffer->set_timestamp(ToTimeDelta(timestamp));
  buffer->set_duration(ToTimeDelta(0));
  return buffer;
}

TEST(DecoderBufferQueueTest, IsEmpty) {
  DecoderBufferQueue queue;
  EXPECT_TRUE(queue.IsEmpty());

  queue.Push(CreateBuffer(0));
  EXPECT_FALSE(queue.IsEmpty());
}

TEST(DecoderBufferQueueTest, Clear) {
  DecoderBufferQueue queue;
  queue.Push(CreateBuffer(0));
  queue.Push(CreateBuffer(1));
  EXPECT_FALSE(queue.IsEmpty());
  EXPECT_EQ(1, queue.Duration().InSeconds());

  queue.Clear();
  EXPECT_TRUE(queue.IsEmpty());
  EXPECT_EQ(0, queue.Duration().InSeconds());
}

TEST(DecoderBufferQueueTest, Duration) {
  DecoderBufferQueue queue;
  EXPECT_EQ(0, queue.Duration().InSeconds());

  queue.Push(CreateBuffer(0));
  EXPECT_EQ(0, queue.Duration().InSeconds());

  queue.Push(CreateBuffer(1));
  EXPECT_EQ(1, queue.Duration().InSeconds());

  queue.Push(CreateBuffer(2));
  EXPECT_EQ(2, queue.Duration().InSeconds());

  queue.Push(CreateBuffer(4));
  EXPECT_EQ(4, queue.Duration().InSeconds());

  queue.Pop();
  EXPECT_EQ(3, queue.Duration().InSeconds());

  queue.Pop();
  EXPECT_EQ(2, queue.Duration().InSeconds());

  queue.Pop();
  EXPECT_EQ(0, queue.Duration().InSeconds());

  queue.Pop();
  EXPECT_EQ(0, queue.Duration().InSeconds());
}

TEST(DecoderBufferQueueTest, Duration_OutOfOrder) {
  DecoderBufferQueue queue;
  queue.Push(CreateBuffer(10));
  queue.Push(CreateBuffer(12));
  EXPECT_EQ(2, queue.Duration().InSeconds());

  // Out of order: duration shouldn't change.
  queue.Push(CreateBuffer(8));
  EXPECT_EQ(2, queue.Duration().InSeconds());

  // Removing first buffer should leave the second buffer as the only buffer
  // included in the duration calculation.
  queue.Pop();
  EXPECT_EQ(0, queue.Duration().InSeconds());

  // Removing second buffer leaves the out-of-order buffer. It shouldn't be
  // included in duration calculations.
  queue.Pop();
  EXPECT_EQ(0, queue.Duration().InSeconds());

  // Push a still-too-early buffer. It shouldn't be included in duration
  // calculations.
  queue.Push(CreateBuffer(11));
  EXPECT_EQ(0, queue.Duration().InSeconds());

  // Push a buffer that's after the earliest valid time. It's a singular valid
  // buffer so duration is still zero.
  queue.Push(CreateBuffer(14));
  EXPECT_EQ(0, queue.Duration().InSeconds());

  // Push a second valid buffer. We should now have a duration.
  queue.Push(CreateBuffer(17));
  EXPECT_EQ(3, queue.Duration().InSeconds());
}

TEST(DecoderBufferQueueTest, Duration_NoTimestamp) {
  // Buffers with no timestamp don't affect duration.
  DecoderBufferQueue queue;
  queue.Push(CreateBuffer(0));
  queue.Push(CreateBuffer(4));
  EXPECT_EQ(4, queue.Duration().InSeconds());

  queue.Push(CreateBuffer(-1));
  EXPECT_EQ(4, queue.Duration().InSeconds());

  queue.Push(CreateBuffer(6));
  EXPECT_EQ(6, queue.Duration().InSeconds());

  queue.Pop();
  EXPECT_EQ(2, queue.Duration().InSeconds());

  queue.Pop();
  EXPECT_EQ(0, queue.Duration().InSeconds());

  queue.Pop();
  EXPECT_EQ(0, queue.Duration().InSeconds());

  queue.Pop();
  EXPECT_EQ(0, queue.Duration().InSeconds());
}

TEST(DecoderBufferQueueTest, DataSize) {
  DecoderBufferQueue queue;
  EXPECT_EQ(queue.data_size(), 0u);

  queue.Push(CreateBuffer(0, 1200u));
  EXPECT_EQ(queue.data_size(), 1200u);

  queue.Push(CreateBuffer(1, 1000u));
  EXPECT_EQ(queue.data_size(), 2200u);

  queue.Pop();
  EXPECT_EQ(queue.data_size(), 1000u);

  queue.Push(CreateBuffer(2, 999u));
  queue.Push(CreateBuffer(3, 999u));
  EXPECT_EQ(queue.data_size(), 2998u);

  queue.Clear();
  EXPECT_EQ(queue.data_size(), 0u);

  queue.Push(CreateBuffer(4, 1400u));
  EXPECT_EQ(queue.data_size(), 1400u);
}

}  // namespace media
