// 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 <string>
#include <vector>

#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string_util.h"
#include "chrome/browser/search/instant_service.h"
#include "chrome/browser/search/instant_service_observer.h"
#include "chrome/browser/search/instant_unittest_base.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/search/instant_search_prerenderer.h"
#include "chrome/common/render_messages.h"
#include "components/variations/entropy_provider.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/mock_render_process_host.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_test_sink.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "url/gurl.h"

class MockInstantServiceObserver : public InstantServiceObserver {
 public:
  MOCK_METHOD0(DefaultSearchProviderChanged, void());
  MOCK_METHOD0(GoogleURLUpdated, void());
};

class MockWebContentsObserver : public content::WebContentsObserver {
 public:
  MOCK_METHOD1(WebContentsDestroyed, void(content::WebContents*));

  // Dumb override to make MSVC happy.
  void Observe_(content::WebContents* contents) {
    content::WebContentsObserver::Observe(contents);
  }

 protected:
  friend class InstantServiceTest;
  FRIEND_TEST_ALL_PREFIXES(InstantServiceTest,
      DispatchDefaultSearchProviderChanged);
  FRIEND_TEST_ALL_PREFIXES(InstantServiceTest, DispatchGoogleURLUpdated);
};

class InstantServiceTest : public InstantUnitTestBase {
 protected:
  virtual void SetUp() OVERRIDE {
    InstantUnitTestBase::SetUpWithoutCacheableNTP();

    instant_service_observer_.reset(new MockInstantServiceObserver());
    instant_service_->AddObserver(instant_service_observer_.get());

    instant_ntp_contents_observer_.reset(new MockWebContentsObserver());
    instant_ntp_contents_observer_->Observe_(
        instant_service_->GetNTPContents());
  }

  virtual void TearDown() OVERRIDE {
    instant_service_->RemoveObserver(instant_service_observer_.get());
    instant_ntp_contents_observer_->Observe_(NULL);
    InstantUnitTestBase::TearDown();
  }

  InstantSearchPrerenderer* GetInstantSearchPrerenderer() {
    return instant_service_->instant_search_prerenderer();
  }

  scoped_ptr<MockInstantServiceObserver> instant_service_observer_;
  scoped_ptr<MockWebContentsObserver> instant_ntp_contents_observer_;
};

TEST_F(InstantServiceTest, DispatchDefaultSearchProviderChanged) {
  EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged())
      .Times(1);
  EXPECT_CALL(*instant_ntp_contents_observer_.get(),
              WebContentsDestroyed(instant_service_->GetNTPContents()))
      .Times(1);

  GURL ntp_url = instant_service_->GetNTPContents()->GetURL();
  const std::string& new_base_url = "https://bar.com/";
  SetDefaultSearchProvider(new_base_url);
  GURL new_ntp_url = instant_service_->GetNTPContents()->GetURL();
  EXPECT_NE(ntp_url, new_ntp_url);
  EXPECT_TRUE(StartsWithASCII(new_ntp_url.spec(), new_base_url, true));
}

TEST_F(InstantServiceTest, DispatchGoogleURLUpdated) {
  EXPECT_CALL(*instant_service_observer_.get(), GoogleURLUpdated()).Times(1);
  EXPECT_CALL(*instant_ntp_contents_observer_.get(),
              WebContentsDestroyed(instant_service_->GetNTPContents()))
      .Times(1);

  GURL ntp_url = instant_service_->GetNTPContents()->GetURL();
  const std::string& new_base_url = "https://www.google.es/";
  NotifyGoogleBaseURLUpdate(new_base_url);
  GURL new_ntp_url = instant_service_->GetNTPContents()->GetURL();
  EXPECT_NE(ntp_url, new_ntp_url);
  EXPECT_TRUE(StartsWithASCII(new_ntp_url.spec(), new_base_url, true));
}

TEST_F(InstantServiceTest, SendsSearchURLsToRenderer) {
  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch",
      "Group1 use_cacheable_ntp:1"));
  scoped_ptr<content::MockRenderProcessHost> rph(
      new content::MockRenderProcessHost(profile()));
  rph->sink().ClearMessages();
  instant_service_->Observe(
      content::NOTIFICATION_RENDERER_PROCESS_CREATED,
      content::Source<content::MockRenderProcessHost>(rph.get()),
      content::NotificationService::NoDetails());
  EXPECT_EQ(1U, rph->sink().message_count());
  const IPC::Message* msg = rph->sink().GetMessageAt(0);
  ASSERT_TRUE(msg);
  std::vector<GURL> search_urls;
  GURL new_tab_page_url;
  ChromeViewMsg_SetSearchURLs::Read(msg, &search_urls, &new_tab_page_url);
  EXPECT_EQ(2U, search_urls.size());
  EXPECT_EQ("https://www.google.com/alt#quux=", search_urls[0].spec());
  EXPECT_EQ("https://www.google.com/url?bar=", search_urls[1].spec());
  EXPECT_EQ("https://www.google.com/newtab", new_tab_page_url.spec());
}

TEST_F(InstantServiceTest, InstantSearchDisabled) {
  // 'prefetch_results' flag is not enabled in field trials. Make sure
  // InstantSearchPrerenderer is not initialized.
  EXPECT_EQ(static_cast<InstantSearchPrerenderer*>(NULL),
            GetInstantSearchPrerenderer());
}

TEST_F(InstantServiceTest,
       ResetInstantSearchPrerenderer_DefaultProviderChanged) {
  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
      "EmbeddedSearch", "Group1 use_cacheable_ntp:1 prefetch_results:1"));
  EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged())
      .Times(2);

  // Set a default search provider that doesn't support Instant.
  TemplateURLData data;
  data.SetURL("https://foobar.com/url?bar={searchTerms}");
  TemplateURL* template_url = new TemplateURL(profile(), data);
  // Takes ownership of |template_url|.
  template_url_service_->Add(template_url);
  template_url_service_->SetDefaultSearchProvider(template_url);

  EXPECT_EQ(static_cast<InstantSearchPrerenderer*>(NULL),
            GetInstantSearchPrerenderer());

  // Set a default search provider that supports Instant and make sure
  // InstantSearchPrerenderer is valid.
  SetDefaultSearchProvider("https://google.com/");
  EXPECT_NE(static_cast<InstantSearchPrerenderer*>(NULL),
            GetInstantSearchPrerenderer());
}

TEST_F(InstantServiceTest, ResetInstantSearchPrerenderer_GoogleBaseURLUpdated) {
  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
      "EmbeddedSearch", "Group1 use_cacheable_ntp:1 prefetch_results:1"));
  EXPECT_CALL(*instant_service_observer_.get(), DefaultSearchProviderChanged())
      .Times(1);
  EXPECT_CALL(*instant_service_observer_.get(), GoogleURLUpdated()).Times(1);

  SetDefaultSearchProvider("https://google.com/");
  InstantSearchPrerenderer* old_prerenderer = GetInstantSearchPrerenderer();
  EXPECT_NE(static_cast<InstantSearchPrerenderer*>(NULL), old_prerenderer);

  const std::string& new_base_url = "https://www.google.es/";
  NotifyGoogleBaseURLUpdate(new_base_url);
  EXPECT_NE(old_prerenderer, GetInstantSearchPrerenderer());
}
