// 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/utf_string_conversions.h"
#include "chrome/browser/speech/speech_recognition_bubble_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/rect.h"

using content::BrowserThread;
using content::WebContents;

namespace speech {

// A mock bubble class which fakes a focus change or recognition cancel by the
// user and closing of the info bubble.
class MockSpeechRecognitionBubble : public SpeechRecognitionBubbleBase {
 public:
  enum BubbleType {
    BUBBLE_TEST_FOCUS_CHANGED,
    BUBBLE_TEST_CLICK_CANCEL,
    BUBBLE_TEST_CLICK_TRY_AGAIN,
  };

  MockSpeechRecognitionBubble(WebContents* web_contents,
                        Delegate* delegate,
                        const gfx::Rect&)
      : SpeechRecognitionBubbleBase(web_contents) {
    VLOG(1) << "MockSpeechRecognitionBubble created";
    MessageLoop::current()->PostTask(
        FROM_HERE, base::Bind(&InvokeDelegate, delegate));
  }

  static void InvokeDelegate(Delegate* delegate) {
    VLOG(1) << "MockSpeechRecognitionBubble invoking delegate for type "
            << type_;
    switch (type_) {
      case BUBBLE_TEST_FOCUS_CHANGED:
        delegate->InfoBubbleFocusChanged();
        break;
      case BUBBLE_TEST_CLICK_CANCEL:
        delegate->InfoBubbleButtonClicked(
            SpeechRecognitionBubble::BUTTON_CANCEL);
        break;
      case BUBBLE_TEST_CLICK_TRY_AGAIN:
        delegate->InfoBubbleButtonClicked(
            SpeechRecognitionBubble::BUTTON_TRY_AGAIN);
        break;
    }
  }

  static void set_type(BubbleType type) {
    type_ = type;
  }
  static BubbleType type() {
    return type_;
  }

  virtual void Show() {}
  virtual void Hide() {}
  virtual void UpdateLayout() {}
  virtual void UpdateImage() {}

 private:
  static BubbleType type_;
};

// The test fixture.
class SpeechRecognitionBubbleControllerTest
    : public SpeechRecognitionBubbleControllerDelegate,
      public BrowserWithTestWindowTest {
 public:
  SpeechRecognitionBubbleControllerTest()
      : BrowserWithTestWindowTest(),
        io_thread_(BrowserThread::IO),  // constructs a new thread and loop
        cancel_clicked_(false),
        try_again_clicked_(false),
        focus_changed_(false),
        controller_(ALLOW_THIS_IN_INITIALIZER_LIST(
            new SpeechRecognitionBubbleController(this))) {
    EXPECT_EQ(NULL, test_fixture_);
    test_fixture_ = this;
  }

  ~SpeechRecognitionBubbleControllerTest() {
    test_fixture_ = NULL;
  }

  // SpeechRecognitionBubbleControllerDelegate methods.
  virtual void InfoBubbleButtonClicked(int session_id,
                                       SpeechRecognitionBubble::Button button) {
    VLOG(1) << "Received InfoBubbleButtonClicked for button " << button;
    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
    if (button == SpeechRecognitionBubble::BUTTON_CANCEL) {
      cancel_clicked_ = true;
    } else if (button == SpeechRecognitionBubble::BUTTON_TRY_AGAIN) {
      try_again_clicked_ = true;
    }
    message_loop()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
  }

  virtual void InfoBubbleFocusChanged(int session_id) {
    VLOG(1) << "Received InfoBubbleFocusChanged";
    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
    focus_changed_ = true;
    message_loop()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
  }

  // testing::Test methods.
  virtual void SetUp() {
    BrowserWithTestWindowTest::SetUp();
    SpeechRecognitionBubble::set_factory(
        &SpeechRecognitionBubbleControllerTest::CreateBubble);
    io_thread_.Start();
  }

  virtual void TearDown() {
    SpeechRecognitionBubble::set_factory(NULL);
    io_thread_.Stop();
    BrowserWithTestWindowTest::TearDown();
  }

  static void ActivateBubble() {
    if (MockSpeechRecognitionBubble::type() !=
        MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED) {
      test_fixture_->controller_->SetBubbleMessage(ASCIIToUTF16("Test"));
    }
  }

  static SpeechRecognitionBubble* CreateBubble(
      WebContents* web_contents,
      SpeechRecognitionBubble::Delegate* delegate,
      const gfx::Rect& element_rect) {
    EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
    // Set up to activate the bubble soon after it gets created, since we test
    // events sent by the bubble and those are handled only when the bubble is
    // active.
    MessageLoop::current()->PostTask(FROM_HERE,
                                     base::Bind(&ActivateBubble));

    // The |tab_contents| parameter would be NULL since the dummy session id
    // passed to CreateBubble would not have matched any active tab. So get a
    // real WebContents pointer from the test fixture and pass that, because
    // the bubble controller registers for tab close notifications which need
    // a valid WebContents.
    TabContents* tab_contents =
        chrome::GetActiveTabContents(test_fixture_->browser());
    if (tab_contents)
      web_contents = tab_contents->web_contents();
    return new MockSpeechRecognitionBubble(web_contents, delegate,
                                           element_rect);
  }

 protected:
  // The main thread of the test is marked as the IO thread and we create a new
  // one for the UI thread.
  content::TestBrowserThread io_thread_;
  bool cancel_clicked_;
  bool try_again_clicked_;
  bool focus_changed_;
  scoped_refptr<SpeechRecognitionBubbleController> controller_;

  static const int kBubbleSessionId;
  static SpeechRecognitionBubbleControllerTest* test_fixture_;
};

SpeechRecognitionBubbleControllerTest*
SpeechRecognitionBubbleControllerTest::test_fixture_ = NULL;

const int SpeechRecognitionBubbleControllerTest::kBubbleSessionId = 1;

MockSpeechRecognitionBubble::BubbleType MockSpeechRecognitionBubble::type_ =
    MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED;

// Test that the speech bubble UI gets created in the UI thread and that the
// focus changed callback comes back in the IO thread.
TEST_F(SpeechRecognitionBubbleControllerTest, TestFocusChanged) {
  MockSpeechRecognitionBubble::set_type(
      MockSpeechRecognitionBubble::BUBBLE_TEST_FOCUS_CHANGED);

  controller_->CreateBubble(kBubbleSessionId, 1, 1, gfx::Rect(1, 1));
  MessageLoop::current()->Run();
  EXPECT_TRUE(focus_changed_);
  EXPECT_FALSE(cancel_clicked_);
  EXPECT_FALSE(try_again_clicked_);
  controller_->CloseBubble();
}

// Test that the speech bubble UI gets created in the UI thread and that the
// recognition cancelled callback comes back in the IO thread.
TEST_F(SpeechRecognitionBubbleControllerTest, TestRecognitionCancelled) {
  MockSpeechRecognitionBubble::set_type(
      MockSpeechRecognitionBubble::BUBBLE_TEST_CLICK_CANCEL);

  controller_->CreateBubble(kBubbleSessionId, 1, 1, gfx::Rect(1, 1));
  MessageLoop::current()->Run();
  EXPECT_TRUE(cancel_clicked_);
  EXPECT_FALSE(try_again_clicked_);
  EXPECT_FALSE(focus_changed_);
  controller_->CloseBubble();
}

// Test that the speech bubble UI gets created in the UI thread and that the
// try-again button click event comes back in the IO thread.
TEST_F(SpeechRecognitionBubbleControllerTest, TestTryAgainClicked) {
  MockSpeechRecognitionBubble::set_type(
      MockSpeechRecognitionBubble::BUBBLE_TEST_CLICK_TRY_AGAIN);

  controller_->CreateBubble(kBubbleSessionId, 1, 1, gfx::Rect(1, 1));
  MessageLoop::current()->Run();
  EXPECT_FALSE(cancel_clicked_);
  EXPECT_TRUE(try_again_clicked_);
  EXPECT_FALSE(focus_changed_);
  controller_->CloseBubble();
}

}  // namespace speech
