// 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 "ppapi/tests/test_audio.h"

#include <string.h>

#include "ppapi/c/ppb_audio_config.h"
#include "ppapi/c/ppb_audio.h"
#include "ppapi/cpp/module.h"
#include "ppapi/tests/testing_instance.h"
#include "ppapi/tests/test_utils.h"

#if defined(__native_client__)
#include "native_client/src/untrusted/irt/irt.h"
#include "ppapi/native_client/src/untrusted/irt_stub/thread_creator.h"
#endif

#define ARRAYSIZE_UNSAFE(a) \
  ((sizeof(a) / sizeof(*(a))) / \
   static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))

#if defined(__native_client__)
namespace {

void GetNaClIrtPpapiHook(struct nacl_irt_ppapihook* hooks) {
  nacl_interface_query(NACL_IRT_PPAPIHOOK_v0_1, hooks, sizeof(*hooks));
}

struct PP_ThreadFunctions g_thread_funcs = {};

void ThreadFunctionsGetter(const struct PP_ThreadFunctions* thread_funcs) {
  g_thread_funcs = *thread_funcs;
}

// In order to check if the thread_create is called, CountingThreadCreate()
// increments this variable. Callers can check if the function is actually
// called by looking at this value.
int g_num_thread_create_called = 0;
int g_num_thread_join_called = 0;

int CountingThreadCreate(uintptr_t* tid,
                         void (*func)(void* thread_argument),
                         void* thread_argument) {
  ++g_num_thread_create_called;
  return g_thread_funcs.thread_create(tid, func, thread_argument);
}

int CountingThreadJoin(uintptr_t tid) {
  ++g_num_thread_join_called;
  return g_thread_funcs.thread_join(tid);
}

// Sets NULL for PP_ThreadFunctions to emulate the situation that
// ppapi_register_thread_creator() is not yet called.
void SetNullThreadFunctions() {
  nacl_irt_ppapihook hooks;
  GetNaClIrtPpapiHook(&hooks);
  PP_ThreadFunctions thread_functions = {};
  hooks.ppapi_register_thread_creator(&thread_functions);
}

void InjectCountingThreadFunctions() {
  // First of all, we extract the system default thread functions.
  // Internally, __nacl_register_thread_creator calls
  // hooks.ppapi_register_thread_creator with default PP_ThreadFunctions
  // instance. ThreadFunctionGetter stores it to g_thread_funcs.
  nacl_irt_ppapihook hooks = { NULL, ThreadFunctionsGetter };
  __nacl_register_thread_creator(&hooks);

  // Here g_thread_funcs stores the thread functions.
  // Inject the CountingThreadCreate.
  PP_ThreadFunctions thread_functions = {
    CountingThreadCreate,
    CountingThreadJoin,
  };
  GetNaClIrtPpapiHook(&hooks);
  hooks.ppapi_register_thread_creator(&thread_functions);
}

// Resets the PP_ThreadFunctions on exit from the scope.
class ScopedThreadFunctionsResetter {
 public:
  ScopedThreadFunctionsResetter() {}
  ~ScopedThreadFunctionsResetter() {
    nacl_irt_ppapihook hooks;
    GetNaClIrtPpapiHook(&hooks);
    __nacl_register_thread_creator(&hooks);
  }
};

}  // namespace
#endif  // __native_client__

REGISTER_TEST_CASE(Audio);

TestAudio::TestAudio(TestingInstance* instance)
    : TestCase(instance),
      audio_callback_method_(NULL),
      audio_callback_event_(instance->pp_instance()),
      test_done_(false),
      audio_interface_(NULL),
      audio_interface_1_0_(NULL),
      audio_config_interface_(NULL),
      core_interface_(NULL) {
}

TestAudio::~TestAudio() {
}

bool TestAudio::Init() {
  audio_interface_ = static_cast<const PPB_Audio_1_1*>(
      pp::Module::Get()->GetBrowserInterface(PPB_AUDIO_INTERFACE_1_1));
  audio_interface_1_0_ = static_cast<const PPB_Audio_1_0*>(
      pp::Module::Get()->GetBrowserInterface(PPB_AUDIO_INTERFACE_1_0));
  audio_config_interface_ = static_cast<const PPB_AudioConfig*>(
      pp::Module::Get()->GetBrowserInterface(PPB_AUDIO_CONFIG_INTERFACE));
  core_interface_ = static_cast<const PPB_Core*>(
      pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
  return audio_interface_ && audio_interface_1_0_ && audio_config_interface_ &&
         core_interface_;
}

void TestAudio::RunTests(const std::string& filter) {
  RUN_TEST(Creation, filter);
  RUN_TEST(DestroyNoStop, filter);
  RUN_TEST(Failures, filter);
  RUN_TEST(AudioCallback1, filter);
  RUN_TEST(AudioCallback2, filter);
  RUN_TEST(AudioCallback3, filter);
  RUN_TEST(AudioCallback4, filter);

#if defined(__native_client__)
  RUN_TEST(AudioThreadCreatorIsRequired, filter);
  RUN_TEST(AudioThreadCreatorIsCalled, filter);
#endif
}

// Test creating audio resources for all guaranteed sample rates and various
// frame counts.
std::string TestAudio::TestCreation() {
  static const PP_AudioSampleRate kSampleRates[] = {
    PP_AUDIOSAMPLERATE_44100,
    PP_AUDIOSAMPLERATE_48000
  };
  static const uint32_t kRequestFrameCounts[] = {
    PP_AUDIOMINSAMPLEFRAMECOUNT,
    PP_AUDIOMAXSAMPLEFRAMECOUNT,
    // Include some "okay-looking" frame counts; check their validity below.
    PP_AUDIOSAMPLERATE_44100 / 100,  // 10ms @ 44.1kHz
    PP_AUDIOSAMPLERATE_48000 / 100,  // 10ms @ 48kHz
    2 * PP_AUDIOSAMPLERATE_44100 / 100,  // 20ms @ 44.1kHz
    2 * PP_AUDIOSAMPLERATE_48000 / 100,  // 20ms @ 48kHz
    1024,
    2048,
    4096
  };
  PP_AudioSampleRate sample_rate = audio_config_interface_->RecommendSampleRate(
      instance_->pp_instance());
  ASSERT_TRUE(sample_rate == PP_AUDIOSAMPLERATE_NONE ||
              sample_rate == PP_AUDIOSAMPLERATE_44100 ||
              sample_rate == PP_AUDIOSAMPLERATE_48000);
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSampleRates); i++) {
    PP_AudioSampleRate sample_rate = kSampleRates[i];

    for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kRequestFrameCounts); j++) {
      // Make a config, create the audio resource, and release the config.
      uint32_t request_frame_count = kRequestFrameCounts[j];
      uint32_t frame_count = audio_config_interface_->RecommendSampleFrameCount(
          instance_->pp_instance(), sample_rate, request_frame_count);
      PP_Resource ac = audio_config_interface_->CreateStereo16Bit(
          instance_->pp_instance(), sample_rate, frame_count);
      ASSERT_TRUE(ac);
      PP_Resource audio = audio_interface_->Create(
          instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
      core_interface_->ReleaseResource(ac);
      ac = 0;

      ASSERT_TRUE(audio);
      ASSERT_TRUE(audio_interface_->IsAudio(audio));

      // Check that the config returned for |audio| matches what we gave it.
      ac = audio_interface_->GetCurrentConfig(audio);
      ASSERT_TRUE(ac);
      ASSERT_TRUE(audio_config_interface_->IsAudioConfig(ac));
      ASSERT_EQ(sample_rate, audio_config_interface_->GetSampleRate(ac));
      ASSERT_EQ(frame_count, audio_config_interface_->GetSampleFrameCount(ac));
      core_interface_->ReleaseResource(ac);
      ac = 0;

      // Start and stop audio playback. The documentation indicates that
      // |StartPlayback()| and |StopPlayback()| may fail, but gives no
      // indication as to why ... so check that they succeed.
      audio_callback_method_ = &TestAudio::AudioCallbackTrivial;
      ASSERT_TRUE(audio_interface_->StartPlayback(audio));
      ASSERT_TRUE(audio_interface_->StopPlayback(audio));
      audio_callback_method_ = NULL;

      core_interface_->ReleaseResource(audio);
    }
  }

  PASS();
}

// Test that releasing the resource without calling |StopPlayback()| "works".
std::string TestAudio::TestDestroyNoStop() {
  PP_Resource ac = CreateAudioConfig(PP_AUDIOSAMPLERATE_44100, 2048);
  ASSERT_TRUE(ac);
  audio_callback_method_ = NULL;
  PP_Resource audio = audio_interface_->Create(
      instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
  core_interface_->ReleaseResource(ac);
  ac = 0;

  ASSERT_TRUE(audio);
  ASSERT_TRUE(audio_interface_->IsAudio(audio));

  // Start playback and release the resource.
  audio_callback_method_ = &TestAudio::AudioCallbackTrivial;
  ASSERT_TRUE(audio_interface_->StartPlayback(audio));
  core_interface_->ReleaseResource(audio);
  audio_callback_method_ = NULL;

  PASS();
}

std::string TestAudio::TestFailures() {
  // Test invalid parameters to |Create()|.

  // We want a valid config for some of our tests of |Create()|.
  PP_Resource ac = CreateAudioConfig(PP_AUDIOSAMPLERATE_44100, 2048);
  ASSERT_TRUE(ac);

  // Failure cases should never lead to the callback being called.
  audio_callback_method_ = NULL;

  // Invalid instance -> failure.
  PP_Resource audio = audio_interface_->Create(
      0, ac, AudioCallbackTrampoline, this);
  ASSERT_EQ(0, audio);

  // Invalid config -> failure.
  audio = audio_interface_->Create(
      instance_->pp_instance(), 0, AudioCallbackTrampoline, this);
  ASSERT_EQ(0, audio);

  // Null callback -> failure.
  audio = audio_interface_->Create(
      instance_->pp_instance(), ac, NULL, NULL);
  ASSERT_EQ(0, audio);

  core_interface_->ReleaseResource(ac);
  ac = 0;

  // Test the other functions with an invalid audio resource.
  ASSERT_FALSE(audio_interface_->IsAudio(0));
  ASSERT_EQ(0, audio_interface_->GetCurrentConfig(0));
  ASSERT_FALSE(audio_interface_->StartPlayback(0));
  ASSERT_FALSE(audio_interface_->StopPlayback(0));

  PASS();
}

// NOTE: |TestAudioCallbackN| assumes that the audio callback is called at least
// once. If the audio stream does not start up correctly or is interrupted this
// may not be the case and these tests will fail. However, in order to properly
// test the audio callbacks, we must have a configuration where audio can
// successfully play, so we assume this is the case on bots.

// This test starts playback and verifies that:
//  1) the audio callback is actually called;
//  2) that |StopPlayback()| waits for the audio callback to finish.
std::string TestAudio::TestAudioCallback1() {
  PP_Resource ac = CreateAudioConfig(PP_AUDIOSAMPLERATE_44100, 1024);
  ASSERT_TRUE(ac);
  audio_callback_method_ = NULL;
  PP_Resource audio = audio_interface_->Create(
      instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
  core_interface_->ReleaseResource(ac);
  ac = 0;

  audio_callback_event_.Reset();
  test_done_ = false;

  audio_callback_method_ = &TestAudio::AudioCallbackTest;
  ASSERT_TRUE(audio_interface_->StartPlayback(audio));

  // Wait for the audio callback to be called.
  audio_callback_event_.Wait();
  ASSERT_TRUE(audio_interface_->StopPlayback(audio));
  test_done_ = true;

  // If any more audio callbacks are generated, we should crash (which is good).
  audio_callback_method_ = NULL;

  core_interface_->ReleaseResource(audio);

  PASS();
}

// This is the same as |TestAudioCallback1()|, except that instead of calling
// |StopPlayback()|, it just releases the resource.
std::string TestAudio::TestAudioCallback2() {
  PP_Resource ac = CreateAudioConfig(PP_AUDIOSAMPLERATE_44100, 1024);
  ASSERT_TRUE(ac);
  audio_callback_method_ = NULL;
  PP_Resource audio = audio_interface_->Create(
      instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
  core_interface_->ReleaseResource(ac);
  ac = 0;

  audio_callback_event_.Reset();
  test_done_ = false;

  audio_callback_method_ = &TestAudio::AudioCallbackTest;
  ASSERT_TRUE(audio_interface_->StartPlayback(audio));

  // Wait for the audio callback to be called.
  audio_callback_event_.Wait();

  core_interface_->ReleaseResource(audio);

  test_done_ = true;

  // If any more audio callbacks are generated, we should crash (which is good).
  audio_callback_method_ = NULL;

  PASS();
}

// This is the same as |TestAudioCallback1()|, except that it attempts a second
// round of |StartPlayback| and |StopPlayback| to make sure the callback
// function still responds when using the same audio resource.
std::string TestAudio::TestAudioCallback3() {
  PP_Resource ac = CreateAudioConfig(PP_AUDIOSAMPLERATE_44100, 1024);
  ASSERT_TRUE(ac);
  audio_callback_method_ = NULL;
  PP_Resource audio = audio_interface_->Create(
      instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
  core_interface_->ReleaseResource(ac);
  ac = 0;

  audio_callback_event_.Reset();
  test_done_ = false;

  audio_callback_method_ = &TestAudio::AudioCallbackTest;
  ASSERT_TRUE(audio_interface_->StartPlayback(audio));

  // Wait for the audio callback to be called.
  audio_callback_event_.Wait();

  ASSERT_TRUE(audio_interface_->StopPlayback(audio));

  // Repeat one more |StartPlayback| & |StopPlayback| cycle, and verify again
  // that the callback function was invoked.
  audio_callback_event_.Reset();
  ASSERT_TRUE(audio_interface_->StartPlayback(audio));

  // Wait for the audio callback to be called.
  audio_callback_event_.Wait();
  ASSERT_TRUE(audio_interface_->StopPlayback(audio));
  test_done_ = true;

  // If any more audio callbacks are generated, we should crash (which is good).
  audio_callback_method_ = NULL;

  core_interface_->ReleaseResource(audio);

  PASS();
}

// This is the same as |TestAudioCallback1()|, except that it uses
// PPB_Audio_1_0.
std::string TestAudio::TestAudioCallback4() {
  PP_Resource ac = CreateAudioConfig(PP_AUDIOSAMPLERATE_44100, 1024);
  ASSERT_TRUE(ac);
  audio_callback_method_ = NULL;
  PP_Resource audio = audio_interface_1_0_->Create(
      instance_->pp_instance(), ac, AudioCallbackTrampoline1_0, this);
  core_interface_->ReleaseResource(ac);
  ac = 0;

  audio_callback_event_.Reset();
  test_done_ = false;

  audio_callback_method_ = &TestAudio::AudioCallbackTest;
  ASSERT_TRUE(audio_interface_1_0_->StartPlayback(audio));

  // Wait for the audio callback to be called.
  audio_callback_event_.Wait();
  ASSERT_TRUE(audio_interface_1_0_->StopPlayback(audio));
  test_done_ = true;

  // If any more audio callbacks are generated, we should crash (which is good).
  audio_callback_method_ = NULL;

  core_interface_->ReleaseResource(audio);

  PASS();
}

#if defined(__native_client__)
// Tests the behavior of the thread_create functions.
// For PPB_Audio_Shared to work properly, the user code must call
// ppapi_register_thread_creator(). This test checks the error handling for the
// case when user code doesn't call ppapi_register_thread_creator().
std::string TestAudio::TestAudioThreadCreatorIsRequired() {
  // We'll inject some thread functions in this test case.
  // Reset them at the end of this case.
  ScopedThreadFunctionsResetter thread_resetter;

  // Set the thread functions to NULLs to emulate the situation where
  // ppapi_register_thread_creator() is not called by user code.
  SetNullThreadFunctions();

  PP_Resource ac = CreateAudioConfig(PP_AUDIOSAMPLERATE_44100, 1024);
  ASSERT_TRUE(ac);
  audio_callback_method_ = NULL;
  PP_Resource audio = audio_interface_->Create(
      instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
  core_interface_->ReleaseResource(ac);
  ac = 0;

  // StartPlayback() fails, because no thread creating function
  // is available.
  ASSERT_FALSE(audio_interface_->StartPlayback(audio));

  // If any more audio callbacks are generated,
  // we should crash (which is good).
  audio_callback_method_ = NULL;

  core_interface_->ReleaseResource(audio);

  PASS();
}

// Tests whether the thread functions passed from the user code are actually
// called.
std::string TestAudio::TestAudioThreadCreatorIsCalled() {
  // We'll inject some thread functions in this test case.
  // Reset them at the end of this case.
  ScopedThreadFunctionsResetter thread_resetter;

  // Inject the thread counting function. In the injected function,
  // when called, g_num_thread_create_called is incremented.
  g_num_thread_create_called = 0;
  g_num_thread_join_called = 0;
  InjectCountingThreadFunctions();

  PP_Resource ac = CreateAudioConfig(PP_AUDIOSAMPLERATE_44100, 1024);
  ASSERT_TRUE(ac);
  audio_callback_method_ = NULL;
  PP_Resource audio = audio_interface_->Create(
      instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
  core_interface_->ReleaseResource(ac);
  ac = 0;

  audio_callback_event_.Reset();
  test_done_ = false;

  audio_callback_method_ = &TestAudio::AudioCallbackTest;
  ASSERT_TRUE(audio_interface_->StartPlayback(audio));

  // Wait for the audio callback to be called.
  audio_callback_event_.Wait();
  // Here, the injected thread_create is called, but thread_join is not yet.
  ASSERT_EQ(1, g_num_thread_create_called);
  ASSERT_EQ(0, g_num_thread_join_called);

  ASSERT_TRUE(audio_interface_->StopPlayback(audio));

  test_done_ = true;

  // Here, the injected thread_join is called.
  ASSERT_EQ(1, g_num_thread_join_called);

  // If any more audio callbacks are generated,
  // we should crash (which is good).
  audio_callback_method_ = NULL;

  core_interface_->ReleaseResource(audio);

  PASS();
}
#endif

// TODO(raymes): Test that actually playback happens correctly, etc.

static void Crash() {
  *static_cast<volatile unsigned*>(NULL) = 0xdeadbeef;
}

// static
void TestAudio::AudioCallbackTrampoline(void* sample_buffer,
                                        uint32_t buffer_size_in_bytes,
                                        PP_TimeDelta latency,
                                        void* user_data) {
  TestAudio* thiz = static_cast<TestAudio*>(user_data);

  // Crash if on the main thread.
  if (thiz->core_interface_->IsMainThread())
    Crash();

  AudioCallbackMethod method = thiz->audio_callback_method_;
  (thiz->*method)(sample_buffer, buffer_size_in_bytes, latency);
}

// static
void TestAudio::AudioCallbackTrampoline1_0(void* sample_buffer,
                                           uint32_t buffer_size_in_bytes,
                                           void* user_data) {
  AudioCallbackTrampoline(sample_buffer, buffer_size_in_bytes, 0.0, user_data);
}

void TestAudio::AudioCallbackTrivial(void* sample_buffer,
                                     uint32_t buffer_size_in_bytes,
                                     PP_TimeDelta latency) {
  if (latency < 0)
    Crash();

  memset(sample_buffer, 0, buffer_size_in_bytes);
}

void TestAudio::AudioCallbackTest(void* sample_buffer,
                                  uint32_t buffer_size_in_bytes,
                                  PP_TimeDelta latency) {
  if (test_done_ || latency < 0)
    Crash();

  memset(sample_buffer, 0, buffer_size_in_bytes);
  audio_callback_event_.Signal();
}

PP_Resource TestAudio::CreateAudioConfig(
    PP_AudioSampleRate sample_rate,
    uint32_t requested_sample_frame_count) {
  uint32_t frame_count = audio_config_interface_->RecommendSampleFrameCount(
      instance_->pp_instance(), sample_rate, requested_sample_frame_count);
  return audio_config_interface_->CreateStereo16Bit(
      instance_->pp_instance(), sample_rate, frame_count);
}
