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

using ::testing::_;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::Invoke;
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 / 100;
static const double kTestVolume = 0.25;

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

  MOCK_METHOD0(OnCreated, void());
  MOCK_METHOD0(OnPlaying, void());
  MOCK_METHOD2(OnPowerMeasured, void(float power_dbfs, bool clipped));
  MOCK_METHOD0(OnPaused, void());
  MOCK_METHOD0(OnError, void());
  MOCK_METHOD2(OnDeviceChange, void(int new_buffer_size, int new_sample_rate));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
};

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

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

 private:
  DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
};

class MockAudioOutputStream : public AudioOutputStream {
 public:
  MOCK_METHOD0(Open, bool());
  MOCK_METHOD1(Start, void(AudioSourceCallback* callback));
  MOCK_METHOD0(Stop, void());
  MOCK_METHOD1(SetVolume, void(double volume));
  MOCK_METHOD1(GetVolume, void(double* volume));
  MOCK_METHOD0(Close, void());

  // Set/get the callback passed to Start().
  AudioSourceCallback* callback() const { return callback_; }
  void SetCallback(AudioSourceCallback* asc) { callback_ = asc; }

 private:
  AudioSourceCallback* callback_;
};

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

static const float kBufferNonZeroData = 1.0f;
ACTION(PopulateBuffer) {
  arg1->Zero();
  // Note: To confirm the buffer will be populated in these tests, it's
  // sufficient that only the first float in channel 0 is set to the value.
  arg1->channel(0)[0] = kBufferNonZeroData;
}

class AudioOutputControllerTest : public testing::Test {
 public:
  AudioOutputControllerTest()
      : audio_manager_(AudioManager::Create()),
        create_event_(false, false),
        play_event_(false, false),
        read_event_(false, false),
        pause_event_(false, false) {
  }

  virtual ~AudioOutputControllerTest() {
  }

 protected:
  void Create(int samples_per_packet) {
    EXPECT_FALSE(create_event_.IsSignaled());
    EXPECT_FALSE(play_event_.IsSignaled());
    EXPECT_FALSE(read_event_.IsSignaled());
    EXPECT_FALSE(pause_event_.IsSignaled());

    params_ = AudioParameters(
        AudioParameters::AUDIO_FAKE, kChannelLayout,
        kSampleRate, kBitsPerSample, samples_per_packet);

    if (params_.IsValid()) {
      EXPECT_CALL(mock_event_handler_, OnCreated())
          .WillOnce(SignalEvent(&create_event_));
    }

    controller_ = AudioOutputController::Create(
        audio_manager_.get(), &mock_event_handler_, params_, std::string(),
        std::string(), &mock_sync_reader_);
    if (controller_.get())
      controller_->SetVolume(kTestVolume);

    EXPECT_EQ(params_.IsValid(), controller_.get() != NULL);
  }

  void Play() {
    // Expect the event handler to receive one OnPlaying() call and one or more
    // OnPowerMeasured() calls.
    EXPECT_CALL(mock_event_handler_, OnPlaying())
        .WillOnce(SignalEvent(&play_event_));
#if defined(AUDIO_POWER_MONITORING)
    EXPECT_CALL(mock_event_handler_, OnPowerMeasured(_, false))
        .Times(AtLeast(1));
#endif

    // During playback, the mock pretends to provide audio data rendered and
    // sent from the render process.
    EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_))
        .Times(AtLeast(1));
    EXPECT_CALL(mock_sync_reader_, Read(_, _))
        .WillRepeatedly(DoAll(PopulateBuffer(),
                              SignalEvent(&read_event_)));
    controller_->Play();
  }

  void Pause() {
    // Expect the event handler to receive one OnPaused() call.
    EXPECT_CALL(mock_event_handler_, OnPaused())
        .WillOnce(SignalEvent(&pause_event_));

    controller_->Pause();
  }

  void ChangeDevice() {
    // Expect the event handler to receive one OnPaying() call and no OnPaused()
    // call.
    EXPECT_CALL(mock_event_handler_, OnPlaying())
        .WillOnce(SignalEvent(&play_event_));
    EXPECT_CALL(mock_event_handler_, OnPaused())
        .Times(0);

    // Simulate a device change event to AudioOutputController from the
    // AudioManager.
    audio_manager_->GetMessageLoop()->PostTask(
        FROM_HERE,
        base::Bind(&AudioOutputController::OnDeviceChange, controller_));
  }

  void Divert(bool was_playing, int num_times_to_be_started) {
    if (was_playing) {
      // Expect the handler to receive one OnPlaying() call as a result of the
      // stream switching.
      EXPECT_CALL(mock_event_handler_, OnPlaying())
          .WillOnce(SignalEvent(&play_event_));
    }

    EXPECT_CALL(mock_stream_, Open())
        .WillOnce(Return(true));
    EXPECT_CALL(mock_stream_, SetVolume(kTestVolume));
    if (num_times_to_be_started > 0) {
      EXPECT_CALL(mock_stream_, Start(NotNull()))
          .Times(num_times_to_be_started)
          .WillRepeatedly(
              Invoke(&mock_stream_, &MockAudioOutputStream::SetCallback));
      EXPECT_CALL(mock_stream_, Stop())
          .Times(num_times_to_be_started);
    }

    controller_->StartDiverting(&mock_stream_);
  }

  void ReadDivertedAudioData() {
    scoped_ptr<AudioBus> dest = AudioBus::Create(params_);
    ASSERT_TRUE(!!mock_stream_.callback());
    const int frames_read =
        mock_stream_.callback()->OnMoreData(dest.get(), AudioBuffersState());
    EXPECT_LT(0, frames_read);
    EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]);
  }

  void Revert(bool was_playing) {
    if (was_playing) {
      // Expect the handler to receive one OnPlaying() call as a result of the
      // stream switching back.
      EXPECT_CALL(mock_event_handler_, OnPlaying())
          .WillOnce(SignalEvent(&play_event_));
    }

    EXPECT_CALL(mock_stream_, Close());

    controller_->StopDiverting();
  }

  void SwitchDevice(bool diverting) {
    if (!diverting) {
      // Expect the current stream to close and a new stream to start
      // playing if not diverting. When diverting, nothing happens
      // until diverting is stopped.
      EXPECT_CALL(mock_event_handler_, OnPlaying())
          .WillOnce(SignalEvent(&play_event_));
    }

    controller_->SwitchOutputDevice(AudioManagerBase::kDefaultDeviceName,
                                    base::Bind(&base::DoNothing));
  }

  void Close() {
    EXPECT_CALL(mock_sync_reader_, Close());

    controller_->Close(base::MessageLoop::QuitClosure());
    base::MessageLoop::current()->Run();
  }

  // These help make test sequences more readable.
  void DivertNeverPlaying() { Divert(false, 0); }
  void DivertWillEventuallyBeTwicePlayed() { Divert(false, 2); }
  void DivertWhilePlaying() { Divert(true, 1); }
  void RevertWasNotPlaying() { Revert(false); }
  void RevertWhilePlaying() { Revert(true); }

  // These synchronize the main thread with key events taking place on other
  // threads.
  void WaitForCreate() { create_event_.Wait(); }
  void WaitForPlay() { play_event_.Wait(); }
  void WaitForReads() {
    // Note: Arbitrarily chosen, but more iterations causes tests to take
    // significantly more time.
    static const int kNumIterations = 3;
    for (int i = 0; i < kNumIterations; ++i) {
      read_event_.Wait();
    }
  }
  void WaitForPause() { pause_event_.Wait(); }

 private:
  base::MessageLoopForIO message_loop_;
  scoped_ptr<AudioManager> audio_manager_;
  MockAudioOutputControllerEventHandler mock_event_handler_;
  MockAudioOutputControllerSyncReader mock_sync_reader_;
  MockAudioOutputStream mock_stream_;
  base::WaitableEvent create_event_;
  base::WaitableEvent play_event_;
  base::WaitableEvent read_event_;
  base::WaitableEvent pause_event_;
  AudioParameters params_;
  scoped_refptr<AudioOutputController> controller_;

  DISALLOW_COPY_AND_ASSIGN(AudioOutputControllerTest);
};

TEST_F(AudioOutputControllerTest, CreateAndClose) {
  Create(kSamplesPerPacket);
  Close();
}

TEST_F(AudioOutputControllerTest, HardwareBufferTooLarge) {
  Create(kSamplesPerPacket * 1000);
}

TEST_F(AudioOutputControllerTest, PlayAndClose) {
  Create(kSamplesPerPacket);
  WaitForCreate();
  Play();
  WaitForPlay();
  WaitForReads();
  Close();
}

TEST_F(AudioOutputControllerTest, PlayPauseClose) {
  Create(kSamplesPerPacket);
  WaitForCreate();
  Play();
  WaitForPlay();
  WaitForReads();
  Pause();
  WaitForPause();
  Close();
}

TEST_F(AudioOutputControllerTest, PlayPausePlayClose) {
  Create(kSamplesPerPacket);
  WaitForCreate();
  Play();
  WaitForPlay();
  WaitForReads();
  Pause();
  WaitForPause();
  Play();
  WaitForPlay();
  Close();
}

TEST_F(AudioOutputControllerTest, PlayDeviceChangeClose) {
  Create(kSamplesPerPacket);
  WaitForCreate();
  Play();
  WaitForPlay();
  WaitForReads();
  ChangeDevice();
  WaitForPlay();
  WaitForReads();
  Close();
}

TEST_F(AudioOutputControllerTest, PlaySwitchDeviceClose) {
  Create(kSamplesPerPacket);
  WaitForCreate();
  Play();
  WaitForPlay();
  WaitForReads();
  SwitchDevice(false);
  WaitForPlay();
  WaitForReads();
  Close();
}

TEST_F(AudioOutputControllerTest, PlayDivertRevertClose) {
  Create(kSamplesPerPacket);
  WaitForCreate();
  Play();
  WaitForPlay();
  WaitForReads();
  DivertWhilePlaying();
  WaitForPlay();
  ReadDivertedAudioData();
  RevertWhilePlaying();
  WaitForPlay();
  WaitForReads();
  Close();
}

TEST_F(AudioOutputControllerTest, PlayDivertSwitchDeviceRevertClose) {
  Create(kSamplesPerPacket);
  WaitForCreate();
  Play();
  WaitForPlay();
  WaitForReads();
  DivertWhilePlaying();
  WaitForPlay();
  SwitchDevice(true);
  ReadDivertedAudioData();
  RevertWhilePlaying();
  WaitForPlay();
  WaitForReads();
  Close();
}

TEST_F(AudioOutputControllerTest, PlayDivertRevertDivertRevertClose) {
  Create(kSamplesPerPacket);
  WaitForCreate();
  Play();
  WaitForPlay();
  WaitForReads();
  DivertWhilePlaying();
  WaitForPlay();
  ReadDivertedAudioData();
  RevertWhilePlaying();
  WaitForPlay();
  WaitForReads();
  DivertWhilePlaying();
  WaitForPlay();
  ReadDivertedAudioData();
  RevertWhilePlaying();
  WaitForPlay();
  WaitForReads();
  Close();
}

TEST_F(AudioOutputControllerTest, DivertPlayPausePlayRevertClose) {
  Create(kSamplesPerPacket);
  WaitForCreate();
  DivertWillEventuallyBeTwicePlayed();
  Play();
  WaitForPlay();
  ReadDivertedAudioData();
  Pause();
  WaitForPause();
  Play();
  WaitForPlay();
  ReadDivertedAudioData();
  RevertWhilePlaying();
  WaitForPlay();
  WaitForReads();
  Close();
}

TEST_F(AudioOutputControllerTest, DivertRevertClose) {
  Create(kSamplesPerPacket);
  WaitForCreate();
  DivertNeverPlaying();
  RevertWasNotPlaying();
  Close();
}

}  // namespace media
