// 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 "chrome/browser/ui/search/instant_search_prerenderer.h"

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_handle.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/browser/prerender/prerender_origin.h"
#include "chrome/browser/prerender/prerender_tab_helper.h"
#include "chrome/browser/prerender/prerender_tracker.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/instant_service.h"
#include "chrome/browser/search/instant_unittest_base.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/search/search_tab_helper.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/render_messages.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/mock_render_process_host.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_test_sink.h"
#include "ui/gfx/size.h"

using base::ASCIIToUTF16;

namespace {

using content::Referrer;
using prerender::Origin;
using prerender::PrerenderContents;
using prerender::PrerenderHandle;
using prerender::PrerenderManager;
using prerender::PrerenderManagerFactory;
using prerender::PrerenderTabHelper;

class DummyPrerenderContents : public PrerenderContents {
 public:
  DummyPrerenderContents(
      PrerenderManager* prerender_manager,
      Profile* profile,
      const GURL& url,
      const Referrer& referrer,
      Origin origin,
      bool call_did_finish_load,
      const content::SessionStorageNamespaceMap& session_storage_namespace_map);

  virtual void StartPrerendering(
      int ALLOW_UNUSED creator_child_id,
      const gfx::Size& ALLOW_UNUSED size,
      content::SessionStorageNamespace* session_storage_namespace,
      net::URLRequestContextGetter* request_context) OVERRIDE;
  virtual bool GetChildId(int* child_id) const OVERRIDE;
  virtual bool GetRouteId(int* route_id) const OVERRIDE;

 private:
  Profile* profile_;
  const GURL url_;
  bool call_did_finish_load_;
  content::SessionStorageNamespaceMap session_storage_namespace_map_;

  DISALLOW_COPY_AND_ASSIGN(DummyPrerenderContents);
};

class DummyPrerenderContentsFactory : public PrerenderContents::Factory {
 public:
  DummyPrerenderContentsFactory(
      bool call_did_finish_load,
      const content::SessionStorageNamespaceMap& session_storage_namespace_map)
      : call_did_finish_load_(call_did_finish_load),
        session_storage_namespace_map_(session_storage_namespace_map) {
  }

  virtual PrerenderContents* CreatePrerenderContents(
      PrerenderManager* prerender_manager,
      Profile* profile,
      const GURL& url,
      const Referrer& referrer,
      Origin origin,
      uint8 experiment_id) OVERRIDE;

 private:
  bool call_did_finish_load_;
  content::SessionStorageNamespaceMap session_storage_namespace_map_;

  DISALLOW_COPY_AND_ASSIGN(DummyPrerenderContentsFactory);
};

DummyPrerenderContents::DummyPrerenderContents(
    PrerenderManager* prerender_manager,
    Profile* profile,
    const GURL& url,
    const Referrer& referrer,
    Origin origin,
    bool call_did_finish_load,
    const content::SessionStorageNamespaceMap& session_storage_namespace_map)
    : PrerenderContents(prerender_manager, profile, url, referrer, origin,
                        PrerenderManager::kNoExperiment),
      profile_(profile),
      url_(url),
      call_did_finish_load_(call_did_finish_load),
      session_storage_namespace_map_(session_storage_namespace_map) {
}

void DummyPrerenderContents::StartPrerendering(
    int ALLOW_UNUSED creator_child_id,
    const gfx::Size& ALLOW_UNUSED size,
    content::SessionStorageNamespace* session_storage_namespace,
    net::URLRequestContextGetter* request_context) {
  prerender_contents_.reset(content::WebContents::CreateWithSessionStorage(
      content::WebContents::CreateParams(profile_),
      session_storage_namespace_map_));
  PrerenderTabHelper::CreateForWebContentsWithPasswordManager(
      prerender_contents_.get(), NULL);
  content::NavigationController::LoadURLParams params(url_);
  prerender_contents_->GetController().LoadURLWithParams(params);
  SearchTabHelper::CreateForWebContents(prerender_contents_.get());

  prerendering_has_started_ = true;
  DCHECK(session_storage_namespace);
  session_storage_namespace_id_ = session_storage_namespace->id();
  NotifyPrerenderStart();

  if (call_did_finish_load_)
    DidFinishLoad(1, url_, true, NULL);
}

bool DummyPrerenderContents::GetChildId(int* child_id) const {
  *child_id = 1;
  return true;
}

bool DummyPrerenderContents::GetRouteId(int* route_id) const {
  *route_id = 1;
  return true;
}

PrerenderContents* DummyPrerenderContentsFactory::CreatePrerenderContents(
    PrerenderManager* prerender_manager,
    Profile* profile,
    const GURL& url,
    const Referrer& referrer,
    Origin origin,
    uint8 experiment_id) {
  return new DummyPrerenderContents(prerender_manager, profile, url, referrer,
                                    origin, call_did_finish_load_,
                                    session_storage_namespace_map_);
}

}  // namespace

class InstantSearchPrerendererTest : public InstantUnitTestBase {
 public:
  InstantSearchPrerendererTest() {}

 protected:
  virtual void SetUp() OVERRIDE {
    ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
        "EmbeddedSearch", "Group1 strk:20 prefetch_results:1"));
    InstantUnitTestBase::SetUp();
  }

  void Init(bool prerender_search_results_base_page,
            bool call_did_finish_load) {
    AddTab(browser(), GURL(url::kAboutBlankURL));

    content::SessionStorageNamespaceMap session_storage_namespace_map;
    session_storage_namespace_map[std::string()] =
        GetActiveWebContents()->GetController().
            GetDefaultSessionStorageNamespace();
    PrerenderManagerFactory::GetForProfile(browser()->profile())->
        SetPrerenderContentsFactory(
            new DummyPrerenderContentsFactory(call_did_finish_load,
                                              session_storage_namespace_map));
    PrerenderManagerFactory::GetForProfile(browser()->profile())->
        OnCookieStoreLoaded();
    if (prerender_search_results_base_page) {
      InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
      prerenderer->Init(session_storage_namespace_map, gfx::Size(640, 480));
      EXPECT_NE(static_cast<PrerenderHandle*>(NULL), prerender_handle());
    }
  }

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

  const GURL& GetPrerenderURL() {
    return GetInstantSearchPrerenderer()->prerender_url_;
  }

  void SetLastQuery(const base::string16& query) {
    GetInstantSearchPrerenderer()->last_instant_suggestion_ =
        InstantSuggestion(query, std::string());
  }

  content::WebContents* prerender_contents() {
    return GetInstantSearchPrerenderer()->prerender_contents();
  }

  bool MessageWasSent(uint32 id) {
    content::MockRenderProcessHost* process =
        static_cast<content::MockRenderProcessHost*>(
            prerender_contents()->GetRenderViewHost()->GetProcess());
    return process->sink().GetFirstMessageMatching(id) != NULL;
  }

  content::WebContents* GetActiveWebContents() const {
    return browser()->tab_strip_model()->GetWebContentsAt(0);
  }

  PrerenderHandle* prerender_handle() {
    return GetInstantSearchPrerenderer()->prerender_handle_.get();
  }

  void PrerenderSearchQuery(const base::string16& query) {
    Init(true, true);
    InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
    prerenderer->Prerender(InstantSuggestion(query, std::string()));
    CommitPendingLoad(&prerender_contents()->GetController());
    EXPECT_TRUE(prerenderer->CanCommitQuery(GetActiveWebContents(), query));
    EXPECT_NE(static_cast<PrerenderHandle*>(NULL), prerender_handle());
  }
};

TEST_F(InstantSearchPrerendererTest, GetSearchTermsFromPrerenderedPage) {
  Init(false, false);
  InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
  GURL url(GetPrerenderURL());
  EXPECT_EQ(GURL("https://www.google.com/instant?ion=1&foo=foo#foo=foo&strk"),
            url);
  EXPECT_EQ(base::UTF16ToASCII(prerenderer->get_last_query()),
            base::UTF16ToASCII(
                chrome::ExtractSearchTermsFromURL(profile(), url)));

  // Assume the prerendered page prefetched search results for the query
  // "flowers".
  SetLastQuery(ASCIIToUTF16("flowers"));
  EXPECT_EQ("flowers", base::UTF16ToASCII(prerenderer->get_last_query()));
  EXPECT_EQ(base::UTF16ToASCII(prerenderer->get_last_query()),
            base::UTF16ToASCII(
                chrome::ExtractSearchTermsFromURL(profile(), url)));
}

TEST_F(InstantSearchPrerendererTest, PrefetchSearchResults) {
  Init(true, true);
  EXPECT_TRUE(prerender_handle()->IsFinishedLoading());
  InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
  prerenderer->Prerender(
      InstantSuggestion(ASCIIToUTF16("flowers"), std::string()));
  EXPECT_EQ("flowers", base::UTF16ToASCII(prerenderer->get_last_query()));
  EXPECT_TRUE(MessageWasSent(
      ChromeViewMsg_SearchBoxSetSuggestionToPrefetch::ID));
}

TEST_F(InstantSearchPrerendererTest, DoNotPrefetchSearchResults) {
  Init(true, false);
  // Page hasn't finished loading yet.
  EXPECT_FALSE(prerender_handle()->IsFinishedLoading());
  InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
  prerenderer->Prerender(
      InstantSuggestion(ASCIIToUTF16("flowers"), std::string()));
  EXPECT_EQ("", base::UTF16ToASCII(prerenderer->get_last_query()));
  EXPECT_FALSE(MessageWasSent(
      ChromeViewMsg_SearchBoxSetSuggestionToPrefetch::ID));
}

TEST_F(InstantSearchPrerendererTest, CanCommitQuery) {
  Init(true, true);
  InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
  base::string16 query = ASCIIToUTF16("flowers");
  prerenderer->Prerender(InstantSuggestion(query, std::string()));
  EXPECT_TRUE(prerenderer->CanCommitQuery(GetActiveWebContents(), query));

  // Make sure InstantSearchPrerenderer::CanCommitQuery() returns false for
  // invalid search queries.
  EXPECT_FALSE(prerenderer->CanCommitQuery(GetActiveWebContents(),
                                           ASCIIToUTF16("joy")));
  EXPECT_FALSE(prerenderer->CanCommitQuery(GetActiveWebContents(),
                                           base::string16()));
}

TEST_F(InstantSearchPrerendererTest, CommitQuery) {
  base::string16 query = ASCIIToUTF16("flowers");
  PrerenderSearchQuery(query);
  InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
  prerenderer->Commit(query);
  EXPECT_TRUE(MessageWasSent(ChromeViewMsg_SearchBoxSubmit::ID));
}

TEST_F(InstantSearchPrerendererTest, CancelPrerenderRequestOnTabChangeEvent) {
  Init(true, true);
  EXPECT_NE(static_cast<PrerenderHandle*>(NULL), prerender_handle());

  // Add a new tab to deactivate the current tab.
  AddTab(browser(), GURL(url::kAboutBlankURL));
  EXPECT_EQ(2, browser()->tab_strip_model()->count());

  // Make sure the pending prerender request is cancelled.
  EXPECT_EQ(static_cast<PrerenderHandle*>(NULL), prerender_handle());
}

TEST_F(InstantSearchPrerendererTest, CancelPendingPrerenderRequest) {
  Init(true, true);
  EXPECT_NE(static_cast<PrerenderHandle*>(NULL), prerender_handle());

  InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
  prerenderer->Cancel();
  EXPECT_EQ(static_cast<PrerenderHandle*>(NULL), prerender_handle());
}

TEST_F(InstantSearchPrerendererTest, PrerenderingAllowed) {
  Init(true, true);
  InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
  content::WebContents* active_tab = GetActiveWebContents();
  EXPECT_EQ(GURL(url::kAboutBlankURL), active_tab->GetURL());

  // Allow prerendering only for search type AutocompleteMatch suggestions.
  AutocompleteMatch search_type_match(NULL, 1100, false,
                                      AutocompleteMatchType::SEARCH_SUGGEST);
  EXPECT_TRUE(AutocompleteMatch::IsSearchType(search_type_match.type));
  EXPECT_TRUE(prerenderer->IsAllowed(search_type_match, active_tab));

  AutocompleteMatch url_type_match(NULL, 1100, true,
                                   AutocompleteMatchType::URL_WHAT_YOU_TYPED);
  EXPECT_FALSE(AutocompleteMatch::IsSearchType(url_type_match.type));
  EXPECT_FALSE(prerenderer->IsAllowed(url_type_match, active_tab));

  // Search results page supports Instant search. InstantSearchPrerenderer is
  // used only when the underlying page doesn't support Instant.
  NavigateAndCommitActiveTab(GURL("https://www.google.com/alt#quux=foo&strk"));
  active_tab = GetActiveWebContents();
  EXPECT_FALSE(chrome::ExtractSearchTermsFromURL(profile(),
                                                 active_tab->GetURL()).empty());
  EXPECT_FALSE(chrome::ShouldPrefetchSearchResultsOnSRP());
  EXPECT_FALSE(prerenderer->IsAllowed(search_type_match, active_tab));
}

TEST_F(InstantSearchPrerendererTest, UsePrerenderPage) {
  PrerenderSearchQuery(ASCIIToUTF16("foo"));

  // Open a search results page. A prerendered page exists for |url|. Make sure
  // the browser swaps the current tab contents with the prerendered contents.
  GURL url("https://www.google.com/alt#quux=foo&strk");
  browser()->OpenURL(content::OpenURLParams(url, Referrer(), CURRENT_TAB,
                                            content::PAGE_TRANSITION_TYPED,
                                            false));
  EXPECT_EQ(GetPrerenderURL(), GetActiveWebContents()->GetURL());
  EXPECT_EQ(static_cast<PrerenderHandle*>(NULL), prerender_handle());
}

TEST_F(InstantSearchPrerendererTest, PrerenderRequestCancelled) {
  PrerenderSearchQuery(ASCIIToUTF16("foo"));

  // Cancel the prerender request.
  InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
  prerenderer->Cancel();
  EXPECT_EQ(static_cast<PrerenderHandle*>(NULL), prerender_handle());

  // Open a search results page. Prerendered page does not exists for |url|.
  // Make sure the browser navigates the current tab to this |url|.
  GURL url("https://www.google.com/alt#quux=foo&strk");
  browser()->OpenURL(content::OpenURLParams(url, Referrer(), CURRENT_TAB,
                                            content::PAGE_TRANSITION_TYPED,
                                            false));
  EXPECT_NE(GetPrerenderURL(), GetActiveWebContents()->GetURL());
  EXPECT_EQ(url, GetActiveWebContents()->GetURL());
}

TEST_F(InstantSearchPrerendererTest,
       CancelPrerenderRequest_SearchQueryMistmatch) {
  PrerenderSearchQuery(ASCIIToUTF16("foo"));

  // Open a search results page. Committed query("pen") doesn't match with the
  // prerendered search query("foo"). Make sure the InstantSearchPrerenderer
  // cancels the active prerender request and the browser navigates the active
  // tab to this |url|.
  GURL url("https://www.google.com/alt#quux=pen&strk");
  browser()->OpenURL(content::OpenURLParams(url, Referrer(), CURRENT_TAB,
                                            content::PAGE_TRANSITION_TYPED,
                                            false));
  EXPECT_NE(GetPrerenderURL(), GetActiveWebContents()->GetURL());
  EXPECT_EQ(url, GetActiveWebContents()->GetURL());
  EXPECT_EQ(static_cast<PrerenderHandle*>(NULL), prerender_handle());
}

TEST_F(InstantSearchPrerendererTest,
       CancelPrerenderRequest_EmptySearchQueryCommitted) {
  PrerenderSearchQuery(ASCIIToUTF16("foo"));

  // Open a search results page. Make sure the InstantSearchPrerenderer cancels
  // the active prerender request upon the receipt of empty search query.
  GURL url("https://www.google.com/alt#quux=&strk");
  browser()->OpenURL(content::OpenURLParams(url, Referrer(), CURRENT_TAB,
                                            content::PAGE_TRANSITION_TYPED,
                                            false));
  EXPECT_NE(GetPrerenderURL(), GetActiveWebContents()->GetURL());
  EXPECT_EQ(url, GetActiveWebContents()->GetURL());
  EXPECT_EQ(static_cast<PrerenderHandle*>(NULL), prerender_handle());
}

TEST_F(InstantSearchPrerendererTest,
       CancelPrerenderRequest_UnsupportedDispositions) {
  PrerenderSearchQuery(ASCIIToUTF16("pen"));

  // Open a search results page. Make sure the InstantSearchPrerenderer cancels
  // the active prerender request for unsupported window dispositions.
  GURL url("https://www.google.com/alt#quux=pen&strk");
  browser()->OpenURL(content::OpenURLParams(url, Referrer(), NEW_FOREGROUND_TAB,
                                            content::PAGE_TRANSITION_TYPED,
                                            false));
  content::WebContents* new_tab =
      browser()->tab_strip_model()->GetWebContentsAt(1);
  EXPECT_NE(GetPrerenderURL(), new_tab->GetURL());
  EXPECT_EQ(url, new_tab->GetURL());
  EXPECT_EQ(static_cast<PrerenderHandle*>(NULL), prerender_handle());
}

class ReuseInstantSearchBasePageTest : public InstantSearchPrerendererTest {
  public:
   ReuseInstantSearchBasePageTest() {}

  protected:
   virtual void SetUp() OVERRIDE {
    ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
        "EmbeddedSearch",
        "Group1 strk:20 prefetch_results:1 reuse_instant_search_base_page:1"));
    InstantUnitTestBase::SetUp();
   }
};

TEST_F(ReuseInstantSearchBasePageTest, CanCommitQuery) {
  Init(true, true);
  InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
  base::string16 query = ASCIIToUTF16("flowers");
  prerenderer->Prerender(InstantSuggestion(query, std::string()));
  EXPECT_TRUE(prerenderer->CanCommitQuery(GetActiveWebContents(), query));

  // When the Instant search base page has finished loading,
  // InstantSearchPrerenderer can commit any search query to the prerendered
  // page (even if it doesn't match the last known suggestion query).
  EXPECT_TRUE(prerenderer->CanCommitQuery(GetActiveWebContents(),
                                           ASCIIToUTF16("joy")));
  // Invalid search query committed.
  EXPECT_FALSE(prerenderer->CanCommitQuery(GetActiveWebContents(),
                                           base::string16()));
}

TEST_F(ReuseInstantSearchBasePageTest,
       CanCommitQuery_InstantSearchBasePageLoadInProgress) {
  Init(true, false);
  InstantSearchPrerenderer* prerenderer = GetInstantSearchPrerenderer();
  base::string16 query = ASCIIToUTF16("flowers");
  prerenderer->Prerender(InstantSuggestion(query, std::string()));

  // When the Instant search base page hasn't finished loading,
  // InstantSearchPrerenderer cannot commit any search query to the base page.
  EXPECT_FALSE(prerenderer->CanCommitQuery(GetActiveWebContents(), query));
  EXPECT_FALSE(prerenderer->CanCommitQuery(GetActiveWebContents(),
                                           ASCIIToUTF16("joy")));
}

#if !defined(OS_IOS) && !defined(OS_ANDROID)
class TestUsePrerenderPage : public InstantSearchPrerendererTest {
 protected:
  virtual void SetUp() OVERRIDE {
    // Disable query extraction flag in field trials.
    ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
        "EmbeddedSearch",
        "Group1 strk:20 query_extraction:0 prefetch_results:1"));
    InstantUnitTestBase::SetUpWithoutQueryExtraction();
  }
};

TEST_F(TestUsePrerenderPage, ExtractSearchTermsAndUsePrerenderPage) {
  PrerenderSearchQuery(ASCIIToUTF16("foo"));

  // Open a search results page. Query extraction flag is disabled in field
  // trials. Search results page URL does not contain search terms replacement
  // key. Make sure UsePrerenderedPage() extracts the search terms from the URL
  // and uses the prerendered page contents.
  GURL url("https://www.google.com/alt#quux=foo");
  browser()->OpenURL(content::OpenURLParams(url, Referrer(), CURRENT_TAB,
                                            content::PAGE_TRANSITION_TYPED,
                                            false));
  EXPECT_EQ(GetPrerenderURL(), GetActiveWebContents()->GetURL());
  EXPECT_EQ(static_cast<PrerenderHandle*>(NULL), prerender_handle());
}
#endif
