// 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.
//
// Tests PPB_MediaStreamAudioTrack interface.

#include "ppapi/tests/test_media_stream_audio_track.h"

// For MSVC.
#define _USE_MATH_DEFINES
#include <math.h>
#include <stddef.h>
#include <stdint.h>

#include <algorithm>

#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/cpp/audio_buffer.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/var.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

REGISTER_TEST_CASE(MediaStreamAudioTrack);

namespace {

// Real constants defined in
// content/renderer/pepper/pepper_media_stream_audio_track_host.cc.
const int32_t kMaxNumberOfBuffers = 1000;
const int32_t kMinDuration = 10;
const int32_t kMaxDuration = 10000;
const int32_t kTimes = 3;
const char kJSCode[] =
    "function gotStream(stream) {"
    "  test_stream = stream;"
    "  var track = stream.getAudioTracks()[0];"
    "  var plugin = document.getElementById('plugin');"
    "  plugin.postMessage(track);"
    "}"
    "var constraints = {"
    "  audio: true,"
    "  video: false,"
    "};"
    "navigator.getUserMedia = "
    "    navigator.getUserMedia || navigator.webkitGetUserMedia;"
    "navigator.getUserMedia(constraints,"
    "    gotStream, function() {});";

const char kSineJSCode[] =
    // Create oscillators for the left and right channels. Use a sine wave,
    // which is the easiest to calculate expected values. The oscillator output
    // is low-pass filtered (as per spec) making comparison hard.
    "var context = new AudioContext();"
    "var l_osc = context.createOscillator();"
    "l_osc.type = \"sine\";"
    "l_osc.frequency.value = 25;"
    "var r_osc = context.createOscillator();"
    "r_osc.type = \"sine\";"
    "r_osc.frequency.value = 100;"
    // Combine the left and right channels.
    "var merger = context.createChannelMerger(2);"
    "merger.channelInterpretation = \"discrete\";"
    "l_osc.connect(merger, 0, 0);"
    "r_osc.connect(merger, 0, 1);"
    "var dest_stream = context.createMediaStreamDestination();"
    "merger.connect(dest_stream);"
    // Dump the generated waveform to a MediaStream output.
    "l_osc.start();"
    "r_osc.start();"
    "var track = dest_stream.stream.getAudioTracks()[0];"
    "var plugin = document.getElementById('plugin');"
    "plugin.postMessage(track);";

// Helper to check if the |sample_rate| is listed in PP_AudioBuffer_SampleRate
// enum.
bool IsSampleRateValid(PP_AudioBuffer_SampleRate sample_rate) {
  switch (sample_rate) {
    case PP_AUDIOBUFFER_SAMPLERATE_8000:
    case PP_AUDIOBUFFER_SAMPLERATE_16000:
    case PP_AUDIOBUFFER_SAMPLERATE_22050:
    case PP_AUDIOBUFFER_SAMPLERATE_32000:
    case PP_AUDIOBUFFER_SAMPLERATE_44100:
    case PP_AUDIOBUFFER_SAMPLERATE_48000:
    case PP_AUDIOBUFFER_SAMPLERATE_96000:
    case PP_AUDIOBUFFER_SAMPLERATE_192000:
      return true;
    default:
      return false;
  }
}

}  // namespace

TestMediaStreamAudioTrack::TestMediaStreamAudioTrack(TestingInstance* instance)
    : TestCase(instance),
      event_(instance_->pp_instance()) {
}

bool TestMediaStreamAudioTrack::Init() {
  return true;
}

TestMediaStreamAudioTrack::~TestMediaStreamAudioTrack() {
}

void TestMediaStreamAudioTrack::RunTests(const std::string& filter) {
  RUN_TEST(Create, filter);
  RUN_TEST(GetBuffer, filter);
  RUN_TEST(Configure, filter);
  RUN_TEST(ConfigureClose, filter);
  RUN_TEST(VerifyWaveform, filter);
}

void TestMediaStreamAudioTrack::HandleMessage(const pp::Var& message) {
  if (message.is_resource()) {
    audio_track_ = pp::MediaStreamAudioTrack(message.AsResource());
  }
  event_.Signal();
}

std::string TestMediaStreamAudioTrack::TestCreate() {
  // Create a track.
  instance_->EvalScript(kJSCode);
  event_.Wait();
  event_.Reset();

  ASSERT_FALSE(audio_track_.is_null());
  ASSERT_FALSE(audio_track_.HasEnded());
  ASSERT_FALSE(audio_track_.GetId().empty());

  // Close the track.
  audio_track_.Close();
  ASSERT_TRUE(audio_track_.HasEnded());
  audio_track_ = pp::MediaStreamAudioTrack();
  PASS();
}

std::string TestMediaStreamAudioTrack::TestGetBuffer() {
  // Create a track.
  instance_->EvalScript(kJSCode);
  event_.Wait();
  event_.Reset();

  ASSERT_FALSE(audio_track_.is_null());
  ASSERT_FALSE(audio_track_.HasEnded());
  ASSERT_FALSE(audio_track_.GetId().empty());

  PP_TimeDelta timestamp = 0.0;

  // Get |kTimes| buffers.
  for (int i = 0; i < kTimes; ++i) {
    TestCompletionCallbackWithOutput<pp::AudioBuffer> cc(
        instance_->pp_instance(), false);
    cc.WaitForResult(audio_track_.GetBuffer(cc.GetCallback()));
    ASSERT_EQ(PP_OK, cc.result());
    pp::AudioBuffer buffer = cc.output();
    ASSERT_FALSE(buffer.is_null());
    ASSERT_TRUE(IsSampleRateValid(buffer.GetSampleRate()));
    ASSERT_EQ(buffer.GetSampleSize(), PP_AUDIOBUFFER_SAMPLESIZE_16_BITS);

    ASSERT_GE(buffer.GetTimestamp(), timestamp);
    timestamp = buffer.GetTimestamp();

    ASSERT_GT(buffer.GetDataBufferSize(), 0U);
    ASSERT_TRUE(buffer.GetDataBuffer() != NULL);

    audio_track_.RecycleBuffer(buffer);

    // A recycled buffer should be invalidated.
    ASSERT_EQ(buffer.GetSampleRate(), PP_AUDIOBUFFER_SAMPLERATE_UNKNOWN);
    ASSERT_EQ(buffer.GetSampleSize(), PP_AUDIOBUFFER_SAMPLESIZE_UNKNOWN);
    ASSERT_EQ(buffer.GetDataBufferSize(), 0U);
    ASSERT_TRUE(buffer.GetDataBuffer() == NULL);
  }

  // Close the track.
  audio_track_.Close();
  ASSERT_TRUE(audio_track_.HasEnded());
  audio_track_ = pp::MediaStreamAudioTrack();
  PASS();
}

std::string TestMediaStreamAudioTrack::CheckConfigure(
    int32_t attrib_list[], int32_t expected_result) {
  TestCompletionCallback cc_configure(instance_->pp_instance(), false);
  cc_configure.WaitForResult(
      audio_track_.Configure(attrib_list, cc_configure.GetCallback()));
  ASSERT_EQ(expected_result, cc_configure.result());
  PASS();
}

std::string TestMediaStreamAudioTrack::CheckGetBuffer(
    int times, int expected_duration) {
  PP_TimeDelta timestamp = 0.0;
  for (int j = 0; j < times; ++j) {
    TestCompletionCallbackWithOutput<pp::AudioBuffer> cc_get_buffer(
        instance_->pp_instance(), false);
    cc_get_buffer.WaitForResult(
        audio_track_.GetBuffer(cc_get_buffer.GetCallback()));
    ASSERT_EQ(PP_OK, cc_get_buffer.result());
    pp::AudioBuffer buffer = cc_get_buffer.output();
    ASSERT_FALSE(buffer.is_null());
    ASSERT_TRUE(IsSampleRateValid(buffer.GetSampleRate()));
    ASSERT_EQ(buffer.GetSampleSize(), PP_AUDIOBUFFER_SAMPLESIZE_16_BITS);

    ASSERT_GE(buffer.GetTimestamp(), timestamp);
    timestamp = buffer.GetTimestamp();

    ASSERT_TRUE(buffer.GetDataBuffer() != NULL);
    if (expected_duration > 0) {
      uint32_t buffer_size = buffer.GetDataBufferSize();
      uint32_t channels = buffer.GetNumberOfChannels();
      uint32_t sample_rate = buffer.GetSampleRate();
      uint32_t bytes_per_frame = channels * 2;
      int32_t duration = expected_duration;
      ASSERT_EQ(buffer_size % bytes_per_frame, 0U);
      ASSERT_EQ(buffer_size,
                (duration * sample_rate * bytes_per_frame) / 1000);
    } else {
      ASSERT_GT(buffer.GetDataBufferSize(), 0U);
    }

    audio_track_.RecycleBuffer(buffer);
  }
  PASS();
}

std::string TestMediaStreamAudioTrack::TestConfigure() {
  // Create a track.
  instance_->EvalScript(kJSCode);
  event_.Wait();
  event_.Reset();

  ASSERT_FALSE(audio_track_.is_null());
  ASSERT_FALSE(audio_track_.HasEnded());
  ASSERT_FALSE(audio_track_.GetId().empty());

  // Perform a |Configure()| with no attributes. This ends up making an IPC
  // call, but the host implementation has a fast-path when there are no changes
  // to the configuration. This test is intended to hit that fast-path and make
  // sure it works correctly.
  {
    int32_t attrib_list[] = {
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE,
    };
    ASSERT_SUBTEST_SUCCESS(CheckConfigure(attrib_list, PP_OK));
  }

  // Configure number of buffers.
  struct {
    int32_t buffers;
    int32_t expect_result;
  } buffers[] = {
    { 8, PP_OK },
    { 100, PP_OK },
    { kMaxNumberOfBuffers, PP_OK },
    { -1, PP_ERROR_BADARGUMENT },
    { kMaxNumberOfBuffers + 1, PP_OK },  // Clipped to max value.
    { 0, PP_OK },  // Use default.
  };
  for (size_t i = 0; i < sizeof(buffers) / sizeof(buffers[0]); ++i) {
    int32_t attrib_list[] = {
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS, buffers[i].buffers,
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE,
    };
    ASSERT_SUBTEST_SUCCESS(CheckConfigure(attrib_list,
                                          buffers[i].expect_result));
    // Get some buffers. This should also succeed when configure fails.
    ASSERT_SUBTEST_SUCCESS(CheckGetBuffer(kTimes, -1));
  }

  // Configure buffer duration.
  struct {
    int32_t duration;
    int32_t expect_result;
  } durations[] = {
    { kMinDuration, PP_OK },
    { 123, PP_OK },
    { kMinDuration - 1, PP_ERROR_BADARGUMENT },
    { kMaxDuration + 1, PP_ERROR_BADARGUMENT },
  };
  for (size_t i = 0; i < sizeof(durations) / sizeof(durations[0]); ++i) {
    int32_t attrib_list[] = {
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_DURATION, durations[i].duration,
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE,
    };
    ASSERT_SUBTEST_SUCCESS(CheckConfigure(attrib_list,
                                          durations[i].expect_result));

    // Get some buffers. This always works, but the buffer size will vary.
    int duration =
        durations[i].expect_result == PP_OK ? durations[i].duration : -1;
    ASSERT_SUBTEST_SUCCESS(CheckGetBuffer(kTimes, duration));
  }
  // Test kMaxDuration separately since each GetBuffer will take 10 seconds.
  {
    int32_t attrib_list[] = {
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_DURATION, kMaxDuration,
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE,
    };
    ASSERT_SUBTEST_SUCCESS(CheckConfigure(attrib_list, PP_OK));
  }

  // Reset the duration to prevent the next part from taking 10 seconds.
  {
    int32_t attrib_list[] = {
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_DURATION, kMinDuration,
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE,
    };
    ASSERT_SUBTEST_SUCCESS(CheckConfigure(attrib_list, PP_OK));
  }

  // Configure should fail while plugin holds buffers.
  {
    TestCompletionCallbackWithOutput<pp::AudioBuffer> cc_get_buffer(
        instance_->pp_instance(), false);
    cc_get_buffer.WaitForResult(
        audio_track_.GetBuffer(cc_get_buffer.GetCallback()));
    ASSERT_EQ(PP_OK, cc_get_buffer.result());
    pp::AudioBuffer buffer = cc_get_buffer.output();
    int32_t attrib_list[] = {
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS, 0,
      PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE,
    };
    TestCompletionCallback cc_configure(instance_->pp_instance(), false);
    cc_configure.WaitForResult(
        audio_track_.Configure(attrib_list, cc_configure.GetCallback()));
    ASSERT_EQ(PP_ERROR_INPROGRESS, cc_configure.result());
    audio_track_.RecycleBuffer(buffer);
  }

  // Close the track.
  audio_track_.Close();
  ASSERT_TRUE(audio_track_.HasEnded());
  audio_track_ = pp::MediaStreamAudioTrack();
  PASS();
}

std::string TestMediaStreamAudioTrack::TestConfigureClose() {
  // Create a track.
  instance_->EvalScript(kJSCode);
  event_.Wait();
  event_.Reset();

  ASSERT_FALSE(audio_track_.is_null());
  ASSERT_FALSE(audio_track_.HasEnded());
  ASSERT_FALSE(audio_track_.GetId().empty());

  // Configure the audio track and close it immediately. The Configure() call
  // should complete.
  int32_t attrib_list[] = {
    PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS, 10,
    PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE,
  };
  TestCompletionCallback cc_configure(instance_->pp_instance(), false);
  int32_t result = audio_track_.Configure(attrib_list,
                                          cc_configure.GetCallback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  audio_track_.Close();
  cc_configure.WaitForResult(result);
  result = cc_configure.result();
  // Unfortunately, we can't control whether the configure succeeds or is
  // aborted.
  ASSERT_TRUE(result == PP_OK || result == PP_ERROR_ABORTED);

  PASS();
}

uint32_t CalculateWaveStartingTime(int16_t sample, int16_t next_sample,
                                   uint32_t period) {
  int16_t slope = next_sample - sample;
  double angle = asin(sample / (double)INT16_MAX);
  if (slope < 0) {
    angle = M_PI - angle;
  }
  if (angle < 0) {
    angle += 2 * M_PI;
  }
  return round(angle * period / (2 * M_PI));
}

std::string TestMediaStreamAudioTrack::TestVerifyWaveform() {
  // Create a track.
  instance_->EvalScript(kSineJSCode);
  event_.Wait();
  event_.Reset();

  ASSERT_FALSE(audio_track_.is_null());
  ASSERT_FALSE(audio_track_.HasEnded());
  ASSERT_FALSE(audio_track_.GetId().empty());

  // Use a weird buffer length and number of buffers.
  const int32_t kBufferSize = 13;
  const int32_t kNumBuffers = 3;

  const uint32_t kChannels = 2;
  const uint32_t kFreqLeft = 25;
  const uint32_t kFreqRight = 100;

  int32_t attrib_list[] = {
    PP_MEDIASTREAMAUDIOTRACK_ATTRIB_DURATION, kBufferSize,
    PP_MEDIASTREAMAUDIOTRACK_ATTRIB_BUFFERS, kNumBuffers,
    PP_MEDIASTREAMAUDIOTRACK_ATTRIB_NONE,
  };
  ASSERT_SUBTEST_SUCCESS(CheckConfigure(attrib_list, PP_OK));

  // Get kNumBuffers buffers and verify they conform to the expected waveform.
  PP_TimeDelta timestamp = 0.0;
  int sample_time = 0;
  uint32_t left_start = 0;
  uint32_t right_start = 0;
  for (int j = 0; j < kNumBuffers; ++j) {
    TestCompletionCallbackWithOutput<pp::AudioBuffer> cc_get_buffer(
        instance_->pp_instance(), false);
    cc_get_buffer.WaitForResult(
        audio_track_.GetBuffer(cc_get_buffer.GetCallback()));
    ASSERT_EQ(PP_OK, cc_get_buffer.result());
    pp::AudioBuffer buffer = cc_get_buffer.output();
    ASSERT_FALSE(buffer.is_null());
    ASSERT_TRUE(IsSampleRateValid(buffer.GetSampleRate()));
    ASSERT_EQ(buffer.GetSampleSize(), PP_AUDIOBUFFER_SAMPLESIZE_16_BITS);
    ASSERT_EQ(buffer.GetNumberOfChannels(), kChannels);
    ASSERT_GE(buffer.GetTimestamp(), timestamp);
    timestamp = buffer.GetTimestamp();

    uint32_t buffer_size = buffer.GetDataBufferSize();
    uint32_t sample_rate = buffer.GetSampleRate();
    uint32_t num_samples = buffer.GetNumberOfSamples();
    uint32_t bytes_per_frame = kChannels * 2;
    ASSERT_EQ(num_samples, (kChannels * kBufferSize * sample_rate) / 1000);
    ASSERT_EQ(buffer_size % bytes_per_frame, 0U);
    ASSERT_EQ(buffer_size, num_samples * 2);

    // Period of sine wave, in samples.
    uint32_t left_period = sample_rate / kFreqLeft;
    uint32_t right_period = sample_rate / kFreqRight;

    int16_t* data_buffer = static_cast<int16_t*>(buffer.GetDataBuffer());
    ASSERT_TRUE(data_buffer != NULL);

    if (j == 0) {
      // The generated wave doesn't necessarily start at 0, so compensate for
      // this.
      left_start = CalculateWaveStartingTime(data_buffer[0], data_buffer[2],
                                             left_period);
      right_start = CalculateWaveStartingTime(data_buffer[1], data_buffer[3],
                                              right_period);
    }

    for (uint32_t sample = 0; sample < num_samples;
         sample += 2, sample_time++) {
      int16_t left = data_buffer[sample];
      int16_t right = data_buffer[sample + 1];
      double angle = (2.0 * M_PI * ((sample_time + left_start) % left_period)) /
          left_period;
      int16_t expected = INT16_MAX * sin(angle);
      // Account for off-by-one errors due to rounding.
      ASSERT_GE(left, std::max<int16_t>(expected, INT16_MIN + 1) - 1);
      ASSERT_LE(left, std::min<int16_t>(expected, INT16_MAX - 1) + 1);

      angle = (2 * M_PI * ((sample_time + right_start) % right_period)) /
          right_period;
      expected = INT16_MAX * sin(angle);
      ASSERT_GE(right, std::max<int16_t>(expected, INT16_MIN + 1) - 1);
      ASSERT_LE(right, std::min<int16_t>(expected, INT16_MAX - 1) + 1);
    }

    audio_track_.RecycleBuffer(buffer);
  }

  PASS();
}
