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

#include <stddef.h>
#include <string>

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "components/google/core/browser/google_util.h"
#include "components/search/search.h"
#include "components/search_engines/search_engine_type.h"
#include "components/search_engines/template_url_service.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "url/gurl.h"

#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
#include "chrome/browser/supervised_user/supervised_user_service.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#include "chrome/browser/supervised_user/supervised_user_url_filter.h"
#endif

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/signin/merge_session_throttling_utils.h"
#endif  // defined(OS_CHROMEOS)

#if !defined(OS_ANDROID)
#include "chrome/browser/search/instant_service.h"
#include "chrome/browser/search/instant_service_factory.h"
#endif

namespace search {

namespace {

const char kServiceWorkerFileName[] = "newtab-serviceworker.js";

bool MatchesOrigin(const GURL& my_url, const GURL& other_url) {
  return my_url.scheme_piece() == other_url.scheme_piece() &&
         my_url.host_piece() == other_url.host_piece() &&
         my_url.port() == other_url.port();
}

}  // namespace

// Returns true if |my_url| matches |other_url| in terms of origin (i.e. host,
// port, and scheme) and path.
// Defined outside of the anonymous namespace so that it's accessible to unit
// tests.
bool MatchesOriginAndPath(const GURL& my_url, const GURL& other_url) {
  return MatchesOrigin(my_url, other_url) &&
         my_url.path_piece() == other_url.path_piece();
}

namespace {

// Status of the New Tab URL for the default Search provider. NOTE: Used in a
// UMA histogram so values should only be added at the end and not reordered.
enum NewTabURLState {
  // Valid URL that should be used.
  NEW_TAB_URL_VALID = 0,

  // Corrupt state (e.g. no profile or template url).
  NEW_TAB_URL_BAD = 1,

  // URL should not be used because in incognito window.
  NEW_TAB_URL_INCOGNITO = 2,

  // No New Tab URL set for provider.
  NEW_TAB_URL_NOT_SET = 3,

  // URL is not secure.
  NEW_TAB_URL_INSECURE = 4,

  // URL should not be used because Suggest is disabled.
  // Not used anymore, see crbug.com/340424.
  // NEW_TAB_URL_SUGGEST_OFF = 5,

  // URL should not be used because it is blocked for a supervised user.
  NEW_TAB_URL_BLOCKED = 6,

  NEW_TAB_URL_MAX
};

const TemplateURL* GetDefaultSearchProviderTemplateURL(Profile* profile) {
  if (profile) {
    TemplateURLService* template_url_service =
        TemplateURLServiceFactory::GetForProfile(profile);
    if (template_url_service)
      return template_url_service->GetDefaultSearchProvider();
  }
  return nullptr;
}

bool IsMatchingServiceWorker(const GURL& my_url, const GURL& document_url) {
  // The origin should match.
  if (!MatchesOrigin(my_url, document_url))
    return false;

  // The url filename should be the new tab page ServiceWorker.
  std::string my_filename = my_url.ExtractFileName();
  if (my_filename != kServiceWorkerFileName)
    return false;

  // The paths up to the filenames should be the same.
  std::string my_path_without_filename = my_url.path();
  my_path_without_filename = my_path_without_filename.substr(
      0, my_path_without_filename.length() - my_filename.length());
  std::string document_filename = document_url.ExtractFileName();
  std::string document_path_without_filename = document_url.path();
  document_path_without_filename = document_path_without_filename.substr(
      0, document_path_without_filename.length() - document_filename.length());

  return my_path_without_filename == document_path_without_filename;
}

// Returns true if |url| matches the NTP URL or the URL of the NTP's associated
// service worker.
bool IsNTPOrServiceWorkerURL(const GURL& url, Profile* profile) {
  if (!url.is_valid())
    return false;

  const GURL new_tab_url(GetNewTabPageURL(profile));
  return new_tab_url.is_valid() && (MatchesOriginAndPath(url, new_tab_url) ||
                                    IsMatchingServiceWorker(url, new_tab_url));
}

bool IsURLAllowedForSupervisedUser(const GURL& url, Profile* profile) {
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
  // If this isn't a supervised user, skip the URL filter check, since it can be
  // fairly expensive.
  if (!profile->IsSupervised())
    return true;
  SupervisedUserService* supervised_user_service =
      SupervisedUserServiceFactory::GetForProfile(profile);
  SupervisedUserURLFilter* url_filter = supervised_user_service->GetURLFilter();
  if (url_filter->GetFilteringBehaviorForURL(url) ==
          SupervisedUserURLFilter::BLOCK) {
    return false;
  }
#endif
  return true;
}

bool ShouldShowLocalNewTab(Profile* profile) {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  return command_line->HasSwitch(switches::kForceLocalNtp) ||
         (base::FeatureList::IsEnabled(features::kUseGoogleLocalNtp) &&
          profile && DefaultSearchProviderIsGoogle(profile));
}

bool ShouldDelayRemoteNTP(const GURL& search_provider_url, Profile* profile) {
#if defined(OS_CHROMEOS)
  // On Chrome OS, if the session hasn't merged yet, we need to avoid loading
  // the remote NTP because that will trigger showing the merge session throttle
  // interstitial page, which can show for 5+ seconds. crbug.com/591530.
  if (merge_session_throttling_utils::ShouldDelayUrl(search_provider_url) &&
      merge_session_throttling_utils::IsSessionRestorePending(profile)) {
    return true;
  }
#endif  // defined(OS_CHROMEOS)
  return false;
}

// Used to look up the URL to use for the New Tab page. Also tracks how we
// arrived at that URL so it can be logged with UMA.
struct NewTabURLDetails {
  NewTabURLDetails(const GURL& url, NewTabURLState state)
      : url(url), state(state) {}

  static NewTabURLDetails ForProfile(Profile* profile) {
    // Incognito has its own New Tab.
    if (profile->IsOffTheRecord())
      return NewTabURLDetails(GURL(), NEW_TAB_URL_INCOGNITO);

    const GURL local_url(chrome::kChromeSearchLocalNtpUrl);

    if (ShouldShowLocalNewTab(profile))
      return NewTabURLDetails(local_url, NEW_TAB_URL_VALID);

    const TemplateURL* template_url =
        GetDefaultSearchProviderTemplateURL(profile);
    if (!profile || !template_url)
      return NewTabURLDetails(local_url, NEW_TAB_URL_BAD);

    GURL search_provider_url(template_url->new_tab_url_ref().ReplaceSearchTerms(
        TemplateURLRef::SearchTermsArgs(base::string16()),
        UIThreadSearchTermsData(profile)));

    if (ShouldDelayRemoteNTP(search_provider_url, profile))
      return NewTabURLDetails(local_url, NEW_TAB_URL_VALID);

    if (!search_provider_url.is_valid())
      return NewTabURLDetails(local_url, NEW_TAB_URL_NOT_SET);
    if (!search_provider_url.SchemeIsCryptographic())
      return NewTabURLDetails(local_url, NEW_TAB_URL_INSECURE);
    if (!IsURLAllowedForSupervisedUser(search_provider_url, profile))
      return NewTabURLDetails(local_url, NEW_TAB_URL_BLOCKED);

    return NewTabURLDetails(search_provider_url, NEW_TAB_URL_VALID);
  }

  const GURL url;
  const NewTabURLState state;
};

bool IsRenderedInInstantProcess(const content::WebContents* contents,
                                Profile* profile) {
#if defined(OS_ANDROID)
  return false;
#else
  const content::RenderProcessHost* process_host =
      contents->GetMainFrame()->GetProcess();
  if (!process_host)
    return false;

  const InstantService* instant_service =
      InstantServiceFactory::GetForProfile(profile);
  if (!instant_service)
    return false;

  return instant_service->IsInstantProcess(process_host->GetID());
#endif
}

}  // namespace

bool DefaultSearchProviderIsGoogle(Profile* profile) {
  return DefaultSearchProviderIsGoogle(
      TemplateURLServiceFactory::GetForProfile(profile));
}

bool DefaultSearchProviderIsGoogle(
    const TemplateURLService* template_url_service) {
  if (!template_url_service)
    return false;
  const TemplateURL* default_provider =
      template_url_service->GetDefaultSearchProvider();
  if (!default_provider)
    return false;
  return default_provider->GetEngineType(
             template_url_service->search_terms_data()) ==
         SearchEngineType::SEARCH_ENGINE_GOOGLE;
}

bool IsNTPURL(const GURL& url, Profile* profile) {
  if (!url.is_valid())
    return false;

  if (!IsInstantExtendedAPIEnabled())
    return url == chrome::kChromeUINewTabURL;

  // TODO(treib,sfiera): Tolerate query params when detecting local NTPs.
  return profile && (IsNTPOrServiceWorkerURL(url, profile) ||
                     url == chrome::kChromeSearchLocalNtpUrl);
}

bool IsInstantNTP(const content::WebContents* contents) {
  if (!contents)
    return false;

  if (contents->ShowingInterstitialPage())
    return false;

  const content::NavigationEntry* entry =
      contents->GetController().GetLastCommittedEntry();
  if (!entry)
    entry = contents->GetController().GetVisibleEntry();
  return NavEntryIsInstantNTP(contents, entry);
}

bool NavEntryIsInstantNTP(const content::WebContents* contents,
                          const content::NavigationEntry* entry) {
  if (!contents || !entry || !IsInstantExtendedAPIEnabled())
    return false;

  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  if (!IsRenderedInInstantProcess(contents, profile))
    return false;

  return IsInstantNTPURL(entry->GetURL(), profile);
}

bool IsInstantNTPURL(const GURL& url, Profile* profile) {
  if (!IsInstantExtendedAPIEnabled())
    return false;

  // TODO(treib,sfiera): Tolerate query params when detecting local NTPs.
  if (url == chrome::kChromeSearchLocalNtpUrl)
    return true;

  GURL new_tab_url(GetNewTabPageURL(profile));
  return new_tab_url.is_valid() && MatchesOriginAndPath(url, new_tab_url);
}

GURL GetNewTabPageURL(Profile* profile) {
  return NewTabURLDetails::ForProfile(profile).url;
}

#if !defined(OS_ANDROID)

bool ShouldAssignURLToInstantRenderer(const GURL& url, Profile* profile) {
  return url.is_valid() && profile && IsInstantExtendedAPIEnabled() &&
         (url.SchemeIs(chrome::kChromeSearchScheme) ||
          IsNTPOrServiceWorkerURL(url, profile));
}

bool ShouldUseProcessPerSiteForInstantURL(const GURL& url, Profile* profile) {
  return ShouldAssignURLToInstantRenderer(url, profile) &&
         (url.host_piece() == chrome::kChromeSearchLocalNtpHost ||
          url.host_piece() == chrome::kChromeSearchRemoteNtpHost);
}

GURL GetEffectiveURLForInstant(const GURL& url, Profile* profile) {
  CHECK(ShouldAssignURLToInstantRenderer(url, profile))
      << "Error granting Instant access.";

  if (url.SchemeIs(chrome::kChromeSearchScheme))
    return url;

  // Replace the scheme with "chrome-search:", and clear the port, since
  // chrome-search is a scheme without port.
  url::Replacements<char> replacements;
  std::string search_scheme(chrome::kChromeSearchScheme);
  replacements.SetScheme(search_scheme.data(),
                         url::Component(0, search_scheme.length()));
  replacements.ClearPort();

  // If this is the URL for a server-provided NTP, replace the host with
  // "remote-ntp".
  std::string remote_ntp_host(chrome::kChromeSearchRemoteNtpHost);
  NewTabURLDetails details = NewTabURLDetails::ForProfile(profile);
  if (details.state == NEW_TAB_URL_VALID &&
      (MatchesOriginAndPath(url, details.url) ||
       IsMatchingServiceWorker(url, details.url))) {
    replacements.SetHost(remote_ntp_host.c_str(),
                         url::Component(0, remote_ntp_host.length()));
  }

  return url.ReplaceComponents(replacements);
}

bool HandleNewTabURLRewrite(GURL* url,
                            content::BrowserContext* browser_context) {
  if (!IsInstantExtendedAPIEnabled())
    return false;

  if (!url->SchemeIs(content::kChromeUIScheme) ||
      url->host() != chrome::kChromeUINewTabHost)
    return false;

  Profile* profile = Profile::FromBrowserContext(browser_context);
  NewTabURLDetails details(NewTabURLDetails::ForProfile(profile));
  UMA_HISTOGRAM_ENUMERATION("NewTabPage.URLState",
                            details.state, NEW_TAB_URL_MAX);
  if (details.url.is_valid()) {
    *url = details.url;
    return true;
  }
  return false;
}

bool HandleNewTabURLReverseRewrite(GURL* url,
                                   content::BrowserContext* browser_context) {
  if (!IsInstantExtendedAPIEnabled())
    return false;

  // Do nothing in incognito.
  Profile* profile = Profile::FromBrowserContext(browser_context);
  if (profile && profile->IsOffTheRecord())
    return false;

  if (IsInstantNTPURL(*url, profile)) {
    *url = GURL(chrome::kChromeUINewTabURL);
    return true;
  }

  return false;
}

#endif  // !defined(OS_ANDROID)

}  // namespace search
