// Copyright 2013 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 <list>

#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/speech/google_streaming_remote_engine.h"
#include "content/browser/speech/speech_recognition_manager_impl.h"
#include "content/browser/speech/speech_recognizer_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test.h"
#include "content/test/content_browser_test_utils.h"
#include "content/test/mock_google_streaming_server.h"
#include "media/audio/mock_audio_manager.h"
#include "media/audio/test_audio_input_controller_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::RunLoop;

namespace content {

class SpeechRecognitionBrowserTest :
    public ContentBrowserTest,
    public MockGoogleStreamingServer::Delegate,
    public media::TestAudioInputControllerDelegate {
 public:
  enum StreamingServerState {
    kIdle,
    kTestAudioControllerOpened,
    kClientConnected,
    kClientAudioUpload,
    kClientAudioUploadComplete,
    kTestAudioControllerClosed,
    kClientDisconnected
  };

  // MockGoogleStreamingServerDelegate methods.
  virtual void OnClientConnected() OVERRIDE {
    ASSERT_EQ(kTestAudioControllerOpened, streaming_server_state_);
    streaming_server_state_ = kClientConnected;
  }

  virtual void OnClientAudioUpload() OVERRIDE {
    if (streaming_server_state_ == kClientConnected)
      streaming_server_state_ = kClientAudioUpload;
  }

  virtual void OnClientAudioUploadComplete() OVERRIDE {
    ASSERT_EQ(kTestAudioControllerClosed, streaming_server_state_);
    streaming_server_state_ = kClientAudioUploadComplete;
  }

  virtual void OnClientDisconnected() OVERRIDE {
    ASSERT_EQ(kClientAudioUploadComplete, streaming_server_state_);
    streaming_server_state_ = kClientDisconnected;
  }

  // media::TestAudioInputControllerDelegate methods.
  virtual void TestAudioControllerOpened(
      media::TestAudioInputController* controller) OVERRIDE {
    ASSERT_EQ(kIdle, streaming_server_state_);
    streaming_server_state_ = kTestAudioControllerOpened;
    const int capture_packet_interval_ms =
        (1000 * controller->audio_parameters().frames_per_buffer()) /
        controller->audio_parameters().sample_rate();
    ASSERT_EQ(GoogleStreamingRemoteEngine::kAudioPacketIntervalMs,
        capture_packet_interval_ms);
    FeedAudioController(500 /* ms */, /*noise=*/ false);
    FeedAudioController(1000 /* ms */, /*noise=*/ true);
    FeedAudioController(1000 /* ms */, /*noise=*/ false);
  }

  virtual void TestAudioControllerClosed(
      media::TestAudioInputController* controller) OVERRIDE {
    ASSERT_EQ(kClientAudioUpload, streaming_server_state_);
    streaming_server_state_ = kTestAudioControllerClosed;
    mock_streaming_server_->MockGoogleStreamingServer::SimulateResult(
        GetGoodSpeechResult());
  }

  // Helper methods used by test fixtures.
  GURL GetTestUrlFromFragment(const std::string fragment) {
    return GURL(GetTestUrl("speech", "web_speech_recognition.html").spec() +
        "#" + fragment);
  }

  std::string GetPageFragment() {
    return shell()->web_contents()->GetURL().ref();
  }

  const StreamingServerState &streaming_server_state() {
    return streaming_server_state_;
  }

 protected:
  // ContentBrowserTest methods.
  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    test_audio_input_controller_factory_.set_delegate(this);
    media::AudioInputController::set_factory_for_testing(
        &test_audio_input_controller_factory_);
    mock_streaming_server_.reset(new MockGoogleStreamingServer(this));
    streaming_server_state_ = kIdle;
  }

  virtual void SetUpOnMainThread() OVERRIDE {
    ASSERT_TRUE(SpeechRecognitionManagerImpl::GetInstance());
    SpeechRecognizerImpl::SetAudioManagerForTesting(
        new media::MockAudioManager(BrowserThread::GetMessageLoopProxyForThread(
            BrowserThread::IO)));
  }

  virtual void TearDownOnMainThread() OVERRIDE {
    SpeechRecognizerImpl::SetAudioManagerForTesting(NULL);
  }

  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
    test_audio_input_controller_factory_.set_delegate(NULL);
    mock_streaming_server_.reset();
  }

 private:
  static void FeedSingleBufferToAudioController(
      scoped_refptr<media::TestAudioInputController> controller,
      size_t buffer_size,
      bool fill_with_noise) {
    DCHECK(controller.get());
    scoped_ptr<uint8[]> audio_buffer(new uint8[buffer_size]);
    if (fill_with_noise) {
      for (size_t i = 0; i < buffer_size; ++i)
        audio_buffer[i] = static_cast<uint8>(127 * sin(i * 3.14F /
            (16 * buffer_size)));
    } else {
      memset(audio_buffer.get(), 0, buffer_size);
    }
    controller->event_handler()->OnData(controller,
                                        audio_buffer.get(),
                                        buffer_size);
  }

  void FeedAudioController(int duration_ms, bool feed_with_noise) {
    media::TestAudioInputController* controller =
        test_audio_input_controller_factory_.controller();
    ASSERT_TRUE(controller);
    const media::AudioParameters& audio_params = controller->audio_parameters();
    const size_t buffer_size = audio_params.GetBytesPerBuffer();
    const int ms_per_buffer = audio_params.frames_per_buffer() * 1000 /
                              audio_params.sample_rate();
    // We can only simulate durations that are integer multiples of the
    // buffer size. In this regard see
    // SpeechRecognitionEngine::GetDesiredAudioChunkDurationMs().
    ASSERT_EQ(0, duration_ms % ms_per_buffer);

    const int n_buffers = duration_ms / ms_per_buffer;
    for (int i = 0; i < n_buffers; ++i) {
      base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
          &FeedSingleBufferToAudioController,
          scoped_refptr<media::TestAudioInputController>(controller),
          buffer_size,
          feed_with_noise));
    }
  }

  SpeechRecognitionResult GetGoodSpeechResult() {
    SpeechRecognitionResult result;
    result.hypotheses.push_back(SpeechRecognitionHypothesis(
        UTF8ToUTF16("Pictures of the moon"), 1.0F));
    return result;
  }

  StreamingServerState streaming_server_state_;
  scoped_ptr<MockGoogleStreamingServer> mock_streaming_server_;
  media::TestAudioInputControllerFactory test_audio_input_controller_factory_;
};

// Simply loads the test page and checks if it was able to create a Speech
// Recognition object in JavaScript, to make sure the Web Speech API is enabled.
IN_PROC_BROWSER_TEST_F(SpeechRecognitionBrowserTest, Precheck) {
  NavigateToURLBlockUntilNavigationsComplete(
      shell(), GetTestUrlFromFragment("precheck"), 2);

  EXPECT_EQ(kIdle, streaming_server_state());
  EXPECT_EQ("success", GetPageFragment());
}

IN_PROC_BROWSER_TEST_F(SpeechRecognitionBrowserTest, OneShotRecognition) {
  NavigateToURLBlockUntilNavigationsComplete(
      shell(), GetTestUrlFromFragment("oneshot"), 2);

  EXPECT_EQ(kClientDisconnected, streaming_server_state());
  EXPECT_EQ("goodresult1", GetPageFragment());
}

}  // namespace content
