// 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 "base/bind.h"
#include "base/environment.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "media/audio/audio_output_controller.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

// TODO(vrk): These tests need to be rewritten! (crbug.com/112500)

using ::testing::_;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::Exactly;
using ::testing::InvokeWithoutArgs;
using ::testing::NotNull;
using ::testing::Return;

namespace media {

static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
static const int kBitsPerSample = 16;
static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
static const int kSamplesPerPacket = kSampleRate / 10;
static const int kHardwareBufferSize = kSamplesPerPacket *
    ChannelLayoutToChannelCount(kChannelLayout) * kBitsPerSample / 8;

class MockAudioOutputControllerEventHandler
    : public AudioOutputController::EventHandler {
 public:
  MockAudioOutputControllerEventHandler() {}

  MOCK_METHOD1(OnCreated, void(AudioOutputController* controller));
  MOCK_METHOD1(OnPlaying, void(AudioOutputController* controller));
  MOCK_METHOD1(OnPaused, void(AudioOutputController* controller));
  MOCK_METHOD2(OnError, void(AudioOutputController* controller,
                             int error_code));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
};

class MockAudioOutputControllerSyncReader
    : public AudioOutputController::SyncReader {
 public:
  MockAudioOutputControllerSyncReader() {}

  MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
  MOCK_METHOD2(Read, int(AudioBus* source, AudioBus* dest));
  MOCK_METHOD0(Close, void());
  MOCK_METHOD0(DataReady, bool());

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
};

ACTION_P(SignalEvent, event) {
  event->Signal();
}

// Custom action to clear a memory buffer.
ACTION(ClearBuffer) {
  arg1->Zero();
}

// Closes AudioOutputController synchronously.
static void CloseAudioController(AudioOutputController* controller) {
  controller->Close(MessageLoop::QuitClosure());
  MessageLoop::current()->Run();
}

class AudioOutputControllerTest : public testing::Test {
 public:
  AudioOutputControllerTest() {}
  virtual ~AudioOutputControllerTest() {}

 protected:
  MessageLoopForIO message_loop_;

 private:
  DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest);
};

TEST_F(AudioOutputControllerTest, CreateAndClose) {
  scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
  if (!audio_manager->HasAudioOutputDevices())
    return;

  MockAudioOutputControllerEventHandler event_handler;

  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .Times(1);

  MockAudioOutputControllerSyncReader sync_reader;
  EXPECT_CALL(sync_reader, Close());

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(
          audio_manager.get(), &event_handler, params, &sync_reader);
  ASSERT_TRUE(controller.get());

  // Close the controller immediately.
  CloseAudioController(controller);
}

TEST_F(AudioOutputControllerTest, PlayPauseClose) {
  scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
  if (!audio_manager->HasAudioOutputDevices())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);
  base::WaitableEvent pause_event(false, false);

  // If OnCreated is called then signal the event.
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));

  // OnPlaying() will be called only once.
  EXPECT_CALL(event_handler, OnPlaying(NotNull()));

  MockAudioOutputControllerSyncReader sync_reader;
  EXPECT_CALL(sync_reader, UpdatePendingBytes(_))
      .Times(AtLeast(2));
  EXPECT_CALL(sync_reader, Read(_, _))
      .WillRepeatedly(DoAll(ClearBuffer(), SignalEvent(&event),
                            Return(4)));
  EXPECT_CALL(sync_reader, DataReady())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(event_handler, OnPaused(NotNull()))
      .WillOnce(InvokeWithoutArgs(&pause_event, &base::WaitableEvent::Signal));
  EXPECT_CALL(sync_reader, Close());

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(
          audio_manager.get(), &event_handler, params, &sync_reader);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  ASSERT_FALSE(pause_event.IsSignaled());
  controller->Play();
  controller->Pause();
  pause_event.Wait();

  // Now stop the controller.
  CloseAudioController(controller);
}

TEST_F(AudioOutputControllerTest, HardwareBufferTooLarge) {
  scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
  if (!audio_manager->HasAudioOutputDevices())
    return;

  // Create an audio device with a very large hardware buffer size.
  MockAudioOutputControllerEventHandler event_handler;

  MockAudioOutputControllerSyncReader sync_reader;
  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout,
                         kSampleRate, kBitsPerSample,
                         kSamplesPerPacket * 1000);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(
          audio_manager.get(), &event_handler, params, &sync_reader);

  // Use assert because we don't stop the device and assume we can't
  // create one.
  ASSERT_FALSE(controller);
}

TEST_F(AudioOutputControllerTest, PlayPausePlayClose) {
  scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
  if (!audio_manager->HasAudioOutputDevices())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));

  // OnPlaying() will be called only once.
  base::WaitableEvent play_event(false, false);
  EXPECT_CALL(event_handler, OnPlaying(NotNull()))
      .WillOnce(InvokeWithoutArgs(&play_event, &base::WaitableEvent::Signal));

  // OnPaused() should never be called since the pause during kStarting is
  // dropped when the second play comes in.
  EXPECT_CALL(event_handler, OnPaused(NotNull()))
      .Times(0);

  MockAudioOutputControllerSyncReader sync_reader;
  EXPECT_CALL(sync_reader, UpdatePendingBytes(_))
      .Times(AtLeast(1));
  EXPECT_CALL(sync_reader, Read(_, _))
      .WillRepeatedly(DoAll(ClearBuffer(), SignalEvent(&event), Return(4)));
  EXPECT_CALL(sync_reader, DataReady())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(sync_reader, Close());

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(
          audio_manager.get(), &event_handler, params, &sync_reader);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  ASSERT_FALSE(play_event.IsSignaled());
  controller->Play();
  controller->Pause();
  controller->Play();
  play_event.Wait();

  // Now stop the controller.
  CloseAudioController(controller);
}

// Ensure state change events are handled.
TEST_F(AudioOutputControllerTest, PlayStateChangeClose) {
  scoped_ptr<AudioManager> audio_manager(AudioManager::Create());
  if (!audio_manager->HasAudioOutputDevices())
    return;

  MockAudioOutputControllerEventHandler event_handler;
  base::WaitableEvent event(false, false);
  EXPECT_CALL(event_handler, OnCreated(NotNull()))
      .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));

  // OnPlaying() will be called once normally and once after being recreated.
  base::WaitableEvent play_event(false, false);
  EXPECT_CALL(event_handler, OnPlaying(NotNull()))
      .Times(2)
      .WillRepeatedly(InvokeWithoutArgs(
          &play_event, &base::WaitableEvent::Signal));

  // OnPaused() should not be called during the state change event.
  EXPECT_CALL(event_handler, OnPaused(NotNull()))
      .Times(0);

  MockAudioOutputControllerSyncReader sync_reader;
  EXPECT_CALL(sync_reader, UpdatePendingBytes(_))
      .Times(AtLeast(1));
  EXPECT_CALL(sync_reader, Read(_, _))
      .WillRepeatedly(DoAll(ClearBuffer(), SignalEvent(&event), Return(4)));
  EXPECT_CALL(sync_reader, DataReady())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(sync_reader, Close());

  AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout,
                         kSampleRate, kBitsPerSample, kSamplesPerPacket);
  scoped_refptr<AudioOutputController> controller =
      AudioOutputController::Create(
          audio_manager.get(), &event_handler, params, &sync_reader);
  ASSERT_TRUE(controller.get());

  // Wait for OnCreated() to be called.
  event.Wait();

  ASSERT_FALSE(play_event.IsSignaled());
  controller->Play();
  play_event.Wait();

  // Force a state change and wait for the stream to come back to playing state.
  play_event.Reset();
  audio_manager->GetMessageLoop()->PostTask(FROM_HERE,
      base::Bind(&AudioOutputController::OnDeviceChange, controller));
  play_event.Wait();

  // Now stop the controller.
  CloseAudioController(controller);
}

}  // namespace media
