// Copyright 2014 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 "chromecast/media/cma/base/buffering_frame_provider.h"

#include <stddef.h>

#include <list>
#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "chromecast/media/cma/test/frame_generator_for_test.h"
#include "chromecast/media/cma/test/mock_frame_consumer.h"
#include "chromecast/media/cma/test/mock_frame_provider.h"
#include "chromecast/public/media/cast_decoder_buffer.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/decoder_buffer.h"
#include "media/base/video_decoder_config.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromecast {
namespace media {

class BufferingFrameProviderTest : public testing::Test {
 public:
  BufferingFrameProviderTest();
  ~BufferingFrameProviderTest() override;

  // Setup the test.
  void Configure(
      size_t frame_count,
      const std::vector<bool>& provider_delayed_pattern,
      const std::vector<bool>& consumer_delayed_pattern);

  // Start the test.
  void Start();

 protected:
  std::unique_ptr<BufferingFrameProvider> buffering_frame_provider_;
  std::unique_ptr<MockFrameConsumer> frame_consumer_;

 private:
  void OnTestTimeout();
  void OnTestCompleted();

  DISALLOW_COPY_AND_ASSIGN(BufferingFrameProviderTest);
};

BufferingFrameProviderTest::BufferingFrameProviderTest() {
}

BufferingFrameProviderTest::~BufferingFrameProviderTest() {
}

void BufferingFrameProviderTest::Configure(
    size_t frame_count,
    const std::vector<bool>& provider_delayed_pattern,
    const std::vector<bool>& consumer_delayed_pattern) {
  DCHECK_GE(frame_count, 1u);

  // Frame generation on the producer and consumer side.
  std::vector<FrameGeneratorForTest::FrameSpec> frame_specs(frame_count);
  for (size_t k = 0; k < frame_specs.size() - 1; k++) {
    frame_specs[k].has_config = (k == 0);
    frame_specs[k].timestamp = base::TimeDelta::FromMilliseconds(40) * k;
    frame_specs[k].size = 512;
    frame_specs[k].has_decrypt_config = ((k % 3) == 0);
  }
  frame_specs.back().is_eos = true;

  std::unique_ptr<FrameGeneratorForTest> frame_generator_provider(
      new FrameGeneratorForTest(frame_specs));
  std::unique_ptr<FrameGeneratorForTest> frame_generator_consumer(
      new FrameGeneratorForTest(frame_specs));

  std::unique_ptr<MockFrameProvider> frame_provider(new MockFrameProvider());
  frame_provider->Configure(provider_delayed_pattern,
                            std::move(frame_generator_provider));

  size_t max_frame_size = 10 * 1024;
  size_t buffer_size = 10 * max_frame_size;
  buffering_frame_provider_.reset(new BufferingFrameProvider(
      std::unique_ptr<CodedFrameProvider>(frame_provider.release()),
      buffer_size, max_frame_size, BufferingFrameProvider::FrameBufferedCB()));

  frame_consumer_.reset(
      new MockFrameConsumer(buffering_frame_provider_.get()));
  frame_consumer_->Configure(consumer_delayed_pattern, false,
                             std::move(frame_generator_consumer));
}

void BufferingFrameProviderTest::Start() {
  frame_consumer_->Start(
      base::Bind(&BufferingFrameProviderTest::OnTestCompleted,
                 base::Unretained(this)));
}

void BufferingFrameProviderTest::OnTestTimeout() {
  ADD_FAILURE() << "Test timed out";
  if (base::MessageLoop::current())
    base::RunLoop::QuitCurrentWhenIdleDeprecated();
}

void BufferingFrameProviderTest::OnTestCompleted() {
  base::RunLoop::QuitCurrentWhenIdleDeprecated();
}

TEST_F(BufferingFrameProviderTest, FastProviderSlowConsumer) {
  bool provider_delayed_pattern[] = { false };
  bool consumer_delayed_pattern[] = { true };

  const size_t frame_count = 100u;
  Configure(
      frame_count,
      std::vector<bool>(
          provider_delayed_pattern,
          provider_delayed_pattern + arraysize(provider_delayed_pattern)),
      std::vector<bool>(
          consumer_delayed_pattern,
          consumer_delayed_pattern + arraysize(consumer_delayed_pattern)));

  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
  message_loop->task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&BufferingFrameProviderTest::Start,
                                base::Unretained(this)));
  base::RunLoop().Run();
}

TEST_F(BufferingFrameProviderTest, SlowProviderFastConsumer) {
  bool provider_delayed_pattern[] = { true };
  bool consumer_delayed_pattern[] = { false };

  const size_t frame_count = 100u;
  Configure(
      frame_count,
      std::vector<bool>(
          provider_delayed_pattern,
          provider_delayed_pattern + arraysize(provider_delayed_pattern)),
      std::vector<bool>(
          consumer_delayed_pattern,
          consumer_delayed_pattern + arraysize(consumer_delayed_pattern)));

  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
  message_loop->task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&BufferingFrameProviderTest::Start,
                                base::Unretained(this)));
  base::RunLoop().Run();
}

TEST_F(BufferingFrameProviderTest, SlowFastProducerConsumer) {
  // Lengths are prime between each other so we can test a lot of combinations.
  bool provider_delayed_pattern[] = {
    true, true, true, true, true,
    false, false, false, false
  };
  bool consumer_delayed_pattern[] = {
    true, true, true, true, true, true, true,
    false, false, false, false, false, false, false
  };

  const size_t frame_count = 100u;
  Configure(
      frame_count,
      std::vector<bool>(
          provider_delayed_pattern,
          provider_delayed_pattern + arraysize(provider_delayed_pattern)),
      std::vector<bool>(
          consumer_delayed_pattern,
          consumer_delayed_pattern + arraysize(consumer_delayed_pattern)));

  std::unique_ptr<base::MessageLoop> message_loop(new base::MessageLoop());
  message_loop->task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&BufferingFrameProviderTest::Start,
                                base::Unretained(this)));
  base::RunLoop().Run();
}

}  // namespace media
}  // namespace chromecast
