// 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 <memory>
#include <set>

#include "base/bind.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/default_tick_clock.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/dns_probe_service_factory.h"
#include "chrome/browser/net/dns_probe_test_util.h"
#include "chrome/browser/net/net_error_tab_helper.h"
#include "chrome/browser/net/secure_dns_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/embedder_support/pref_names.h"
#include "components/error_page/common/net_error_info.h"
#include "components/google/core/common/google_util.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/url_loader_interceptor.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/net_errors.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "services/network/public/cpp/features.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_WIN)
#include "base/win/win_util.h"
#endif

using base::BindOnce;
using base::BindRepeating;
using base::FilePath;
using base::Unretained;
using content::BrowserThread;
using content::WebContents;
using error_page::DnsProbeStatus;
using net::URLRequestFailedJob;
using ui_test_utils::NavigateToURL;

namespace chrome_browser_net {

namespace {

// Wraps DnsProbeService and delays probes until someone calls
// StartDelayedProbes.  This allows the DnsProbeBrowserTest to enforce a
// stricter ordering of events.
class DelayingDnsProbeService : public DnsProbeService {
 public:
  DelayingDnsProbeService(
      const DnsProbeServiceFactory::NetworkContextGetter&
          network_context_getter,
      const DnsProbeServiceFactory::DnsConfigChangeManagerGetter&
          dns_config_change_manager_getter)
      : dns_probe_service_impl_(DnsProbeServiceFactory::CreateForTesting(
            network_context_getter,
            dns_config_change_manager_getter,
            base::DefaultTickClock::GetInstance())) {}

  ~DelayingDnsProbeService() override { EXPECT_TRUE(delayed_probes_.empty()); }

  static std::unique_ptr<KeyedService> Create(
      const DnsProbeServiceFactory::NetworkContextGetter&
          network_context_getter,
      const DnsProbeServiceFactory::DnsConfigChangeManagerGetter&
          dns_config_change_manager_getter,
      content::BrowserContext* context) {
    return std::make_unique<DelayingDnsProbeService>(
        network_context_getter, dns_config_change_manager_getter);
  }

  void ProbeDns(ProbeCallback callback) override {
    delayed_probes_.push_back(std::move(callback));
  }

  net::DnsConfigOverrides GetCurrentConfigOverridesForTesting() override {
    return dns_probe_service_impl_->GetCurrentConfigOverridesForTesting();
  }

  void StartDelayedProbes() {
    CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

    std::vector<ProbeCallback> probes;
    probes.swap(delayed_probes_);

    for (std::vector<ProbeCallback>::iterator i = probes.begin();
         i != probes.end(); ++i) {
      dns_probe_service_impl_->ProbeDns(std::move(*i));
    }
  }

  int delayed_probe_count() const {
    CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    return delayed_probes_.size();
  }

 private:
  std::unique_ptr<DnsProbeService> dns_probe_service_impl_;
  std::vector<ProbeCallback> delayed_probes_;
};

class DnsProbeBrowserTest : public InProcessBrowserTest {
 public:
  DnsProbeBrowserTest();
  ~DnsProbeBrowserTest() override;

  void SetUpOnMainThread() override;
  void TearDownOnMainThread() override;

 protected:
  bool InterceptURLLoaderRequest(
      content::URLLoaderInterceptor::RequestParams* params);

  // Sets the browser object that other methods apply to, and that has the
  // DnsProbeStatus messages of its currently active tab monitored.
  void SetActiveBrowser(Browser* browser);

  // Sets the results the FakeHostResolver will return for the current config
  // and Google config DnsProbeRunners. Since this mocks out the NetworkContext
  // and HostResolver used by the DnsProbeService it doesn't really give an
  // end-to-end test, but content::TestHostResolver mocks don't affect the
  // probes since they use HostResolverSource::DNS, so this is the best that
  // can be done currently.
  void SetFakeHostResolverResults(
      std::vector<FakeHostResolver::SingleResult> current_config_results,
      std::vector<FakeHostResolver::SingleResult> google_config_results);

  void NavigateToDnsError();
  void NavigateToOtherError();

  void StartDelayedProbes(int expected_delayed_probe_count);
  DnsProbeStatus WaitForSentStatus();
  int pending_status_count() const { return dns_probe_status_queue_.size(); }

  std::string Title();
  bool PageContains(const std::string& expected);

  // Checks that the error page is being displayed with the specified status
  // text.  The status text should be either a network error or DNS probe
  // status.
  void ExpectDisplayingErrorPage(const std::string& status_text);

 private:
  void OnDnsProbeStatusSent(DnsProbeStatus dns_probe_status);

  network::mojom::NetworkContext* GetNetworkContext() {
    return network_context_.get();
  }

  mojo::Remote<network::mojom::DnsConfigChangeManager>
  GetDnsConfigChangeManager();

  std::unique_ptr<FakeHostResolverNetworkContext> network_context_;
  std::unique_ptr<FakeDnsConfigChangeManager> dns_config_change_manager_;
  DelayingDnsProbeService* delaying_dns_probe_service_;

  // Browser that methods apply to.
  Browser* active_browser_;
  // Helper that current has its DnsProbeStatus messages monitored.
  NetErrorTabHelper* monitored_tab_helper_;

  std::unique_ptr<base::RunLoop> awaiting_dns_probe_status_run_loop_;
  // Queue of statuses received but not yet consumed by WaitForSentStatus().
  std::list<DnsProbeStatus> dns_probe_status_queue_;

  std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_;
};

DnsProbeBrowserTest::DnsProbeBrowserTest()
    : active_browser_(nullptr), monitored_tab_helper_(nullptr) {}

DnsProbeBrowserTest::~DnsProbeBrowserTest() {
  // No tests should have any unconsumed probe statuses.
  EXPECT_EQ(0, pending_status_count());
}

void DnsProbeBrowserTest::SetUpOnMainThread() {
  NetErrorTabHelper::set_state_for_testing(NetErrorTabHelper::TESTING_DEFAULT);

  browser()->profile()->GetPrefs()->SetBoolean(
      embedder_support::kAlternateErrorPagesEnabled, true);

  ASSERT_TRUE(embedded_test_server()->Start());

  url_loader_interceptor_ = std::make_unique<content::URLLoaderInterceptor>(
      base::BindRepeating(&DnsProbeBrowserTest::InterceptURLLoaderRequest,
                          base::Unretained(this)));

  SetActiveBrowser(browser());
}

void DnsProbeBrowserTest::TearDownOnMainThread() {
  url_loader_interceptor_.reset();

  NetErrorTabHelper::set_state_for_testing(NetErrorTabHelper::TESTING_DEFAULT);
}

bool DnsProbeBrowserTest::InterceptURLLoaderRequest(
    content::URLLoaderInterceptor::RequestParams* params) {
  if (params->url_request.url.spec() == "http://mock.http/title2.html") {
    content::URLLoaderInterceptor::WriteResponse("chrome/test/data/title2.html",
                                                 params->client.get());
    return true;
  }

  // Just returning false is enough to respond to http(s)://mock.failed.request
  // requests, which are the only requests that come in besides the LinkDoctor
  // requests.
  return false;
}

void DnsProbeBrowserTest::SetActiveBrowser(Browser* browser) {
  delaying_dns_probe_service_ = static_cast<DelayingDnsProbeService*>(
      DnsProbeServiceFactory::GetInstance()->SetTestingFactoryAndUse(
          browser->profile(),
          base::BindRepeating(
              &DelayingDnsProbeService::Create,
              base::BindRepeating(&DnsProbeBrowserTest::GetNetworkContext,
                                  base::Unretained(this)),
              base::BindRepeating(
                  &DnsProbeBrowserTest::GetDnsConfigChangeManager,
                  base::Unretained(this)))));
  // If currently watching a NetErrorTabHelper, stop doing so before start
  // watching another.
  if (monitored_tab_helper_) {
    monitored_tab_helper_->set_dns_probe_status_snoop_callback_for_testing(
        NetErrorTabHelper::DnsProbeStatusSnoopCallback());
  }
  active_browser_ = browser;
  monitored_tab_helper_ = NetErrorTabHelper::FromWebContents(
      active_browser_->tab_strip_model()->GetActiveWebContents());
  monitored_tab_helper_->set_dns_probe_status_snoop_callback_for_testing(
      BindRepeating(&DnsProbeBrowserTest::OnDnsProbeStatusSent,
                    Unretained(this)));
}

void DnsProbeBrowserTest::SetFakeHostResolverResults(
    std::vector<FakeHostResolver::SingleResult> current_config_results,
    std::vector<FakeHostResolver::SingleResult> google_config_results) {
  ASSERT_FALSE(network_context_);

  network_context_ = std::make_unique<FakeHostResolverNetworkContext>(
      std::move(current_config_results), std::move(google_config_results));
}

void DnsProbeBrowserTest::NavigateToDnsError() {
  NavigateToURL(active_browser_, URLRequestFailedJob::GetMockHttpUrl(
                                     net::ERR_NAME_NOT_RESOLVED));
}

void DnsProbeBrowserTest::NavigateToOtherError() {
  NavigateToURL(active_browser_, URLRequestFailedJob::GetMockHttpUrl(
                                     net::ERR_CONNECTION_REFUSED));
}

void DnsProbeBrowserTest::StartDelayedProbes(int expected_delayed_probe_count) {
  ASSERT_TRUE(delaying_dns_probe_service_);

  int actual_delayed_probe_count =
      delaying_dns_probe_service_->delayed_probe_count();
  EXPECT_EQ(expected_delayed_probe_count, actual_delayed_probe_count);

  delaying_dns_probe_service_->StartDelayedProbes();
}

DnsProbeStatus DnsProbeBrowserTest::WaitForSentStatus() {
  CHECK(!awaiting_dns_probe_status_run_loop_);
  while (dns_probe_status_queue_.empty()) {
    awaiting_dns_probe_status_run_loop_ = std::make_unique<base::RunLoop>();
    awaiting_dns_probe_status_run_loop_->Run();
    awaiting_dns_probe_status_run_loop_ = nullptr;
  }

  CHECK(!dns_probe_status_queue_.empty());
  DnsProbeStatus status = dns_probe_status_queue_.front();
  dns_probe_status_queue_.pop_front();
  return status;
}

// Check title by roundtripping to renderer, to make sure any probe results
// sent before this have been applied.
std::string DnsProbeBrowserTest::Title() {
  std::string title;

  WebContents* contents =
      active_browser_->tab_strip_model()->GetActiveWebContents();

  return content::EvalJs(contents, "document.title;").ExtractString();
}

// Check text by roundtripping to renderer, to make sure any probe results
// sent before this have been applied.
bool DnsProbeBrowserTest::PageContains(const std::string& expected) {
  std::string text_content =
      content::EvalJs(
          active_browser_->tab_strip_model()->GetActiveWebContents(),
          "document.body.textContent;")
          .ExtractString();

  return text_content.find(expected) != std::string::npos;
}

void DnsProbeBrowserTest::ExpectDisplayingErrorPage(
    const std::string& status_text) {
  EXPECT_FALSE(PageContains("http://mock.http/title2.html"));
  EXPECT_TRUE(PageContains(status_text));
}

void DnsProbeBrowserTest::OnDnsProbeStatusSent(
    DnsProbeStatus dns_probe_status) {
  dns_probe_status_queue_.push_back(dns_probe_status);
  if (awaiting_dns_probe_status_run_loop_)
    awaiting_dns_probe_status_run_loop_->Quit();
}

mojo::Remote<network::mojom::DnsConfigChangeManager>
DnsProbeBrowserTest::GetDnsConfigChangeManager() {
  mojo::Remote<network::mojom::DnsConfigChangeManager>
      dns_config_change_manager_remote;
  dns_config_change_manager_ = std::make_unique<FakeDnsConfigChangeManager>(
      dns_config_change_manager_remote.BindNewPipeAndPassReceiver());
  return dns_config_change_manager_remote;
}

// Test Fixture for tests where the DNS probes should succeed.
class DnsProbeSuccessfulProbesTest : public DnsProbeBrowserTest {
  void SetUpOnMainThread() override {
    SetFakeHostResolverResults({{net::OK, net::ResolveErrorInfo(net::OK),
                                 FakeHostResolver::kOneAddressResponse}},
                               {{net::OK, net::ResolveErrorInfo(net::OK),
                                 FakeHostResolver::kOneAddressResponse}});
    DnsProbeBrowserTest::SetUpOnMainThread();
  }
};

// Test Fixture for tests where the DNS probes should not resolve.
class DnsProbeFailingProbesTest : public DnsProbeBrowserTest {
  void SetUpOnMainThread() override {
    SetFakeHostResolverResults(
        {{net::ERR_NAME_NOT_RESOLVED,
          net::ResolveErrorInfo(net::ERR_NAME_NOT_RESOLVED),
          FakeHostResolver::kNoResponse}},
        {{net::ERR_NAME_NOT_RESOLVED,
          net::ResolveErrorInfo(net::ERR_NAME_NOT_RESOLVED),
          FakeHostResolver::kNoResponse}});
    DnsProbeBrowserTest::SetUpOnMainThread();
  }
};

class DnsProbeCurrentConfigFailingProbesTest : public DnsProbeBrowserTest {
 protected:
  void SetUpOnMainThread() override {
    SetFakeHostResolverResults(
        {{net::ERR_NAME_NOT_RESOLVED,
          net::ResolveErrorInfo(net::ERR_NAME_NOT_RESOLVED),
          FakeHostResolver::kNoResponse}},
        {{net::OK, net::ResolveErrorInfo(net::OK),
          FakeHostResolver::kOneAddressResponse}});
    DnsProbeBrowserTest::SetUpOnMainThread();
  }
};

class DnsProbeCurrentSecureConfigFailingProbesTest
    : public DnsProbeBrowserTest {
 protected:
  void SetUpOnMainThread() override {
#if defined(OS_WIN)
    // Mark as not enterprise managed to prevent the secure DNS mode from
    // being downgraded to off.
    base::win::ScopedDomainStateForTesting scoped_domain(false);
#endif

    PrefService* local_state = g_browser_process->local_state();
    local_state->SetString(prefs::kDnsOverHttpsMode,
                           SecureDnsConfig::kModeSecure);
    local_state->SetString(prefs::kDnsOverHttpsTemplates,
                           "https://bar.test/dns-query{?dns}");

    SetFakeHostResolverResults(
        {{net::ERR_NAME_NOT_RESOLVED,
          net::ResolveErrorInfo(net::ERR_NAME_NOT_RESOLVED),
          FakeHostResolver::kNoResponse}},
        {{net::OK, net::ResolveErrorInfo(net::OK),
          FakeHostResolver::kOneAddressResponse}});
    DnsProbeBrowserTest::SetUpOnMainThread();
  }
};

// Test Fixture for tests where the DNS probes should fail to connect to a DNS
// server (timeout or unreachable host).
class DnsProbeUnreachableProbesTest : public DnsProbeBrowserTest {
  void SetUpOnMainThread() override {
    SetFakeHostResolverResults({{net::ERR_NAME_NOT_RESOLVED,
                                 net::ResolveErrorInfo(net::ERR_DNS_TIMED_OUT),
                                 FakeHostResolver::kNoResponse}},
                               {{net::ERR_NAME_NOT_RESOLVED,
                                 net::ResolveErrorInfo(net::ERR_DNS_TIMED_OUT),
                                 FakeHostResolver::kNoResponse}});
    DnsProbeBrowserTest::SetUpOnMainThread();
  }
};

// Make sure probes don't break non-DNS error.
IN_PROC_BROWSER_TEST_F(DnsProbeSuccessfulProbesTest, OtherErrorWith) {
  NavigateToOtherError();
  ExpectDisplayingErrorPage("ERR_CONNECTION_REFUSED");
}

IN_PROC_BROWSER_TEST_F(DnsProbeCurrentConfigFailingProbesTest, BadConfig) {
  NavigateToDnsError();

  EXPECT_EQ(error_page::DNS_PROBE_STARTED, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("DNS_PROBE_STARTED");
  EXPECT_EQ(0, pending_status_count());

  StartDelayedProbes(1);

  EXPECT_EQ(error_page::DNS_PROBE_FINISHED_BAD_CONFIG, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("DNS_PROBE_FINISHED_BAD_CONFIG");
}

#if defined(OS_WIN)
// https://crbug.com/1226818 Test is flaky on WIN builders.
#define MAYBE_BadSecureConfig DISABLED_BadSecureConfig
#else
#define MAYBE_BadSecureConfig BadSecureConfig
#endif
IN_PROC_BROWSER_TEST_F(DnsProbeCurrentSecureConfigFailingProbesTest,
                       MAYBE_BadSecureConfig) {
  NavigateToDnsError();

  EXPECT_EQ(error_page::DNS_PROBE_STARTED, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("DNS_PROBE_STARTED");
  EXPECT_EQ(0, pending_status_count());

  StartDelayedProbes(1);

  EXPECT_EQ(error_page::DNS_PROBE_FINISHED_BAD_SECURE_CONFIG,
            WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("DNS_PROBE_FINISHED_BAD_SECURE_CONFIG");
}

// Make sure probes update DNS error page properly when they're supposed to.
IN_PROC_BROWSER_TEST_F(DnsProbeUnreachableProbesTest, NoInternetProbeResult) {
  NavigateToDnsError();

  EXPECT_EQ(error_page::DNS_PROBE_STARTED, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("DNS_PROBE_STARTED");
  EXPECT_EQ(0, pending_status_count());

  StartDelayedProbes(1);

  EXPECT_EQ(error_page::DNS_PROBE_FINISHED_NO_INTERNET, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("DNS_PROBE_FINISHED_NO_INTERNET");
}

// Double-check to make sure sync failures don't explode.
IN_PROC_BROWSER_TEST_F(DnsProbeFailingProbesTest, SyncFailure) {
  NavigateToDnsError();

  EXPECT_EQ(error_page::DNS_PROBE_STARTED, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("DNS_PROBE_STARTED");
  EXPECT_EQ(0, pending_status_count());

  StartDelayedProbes(1);

  EXPECT_EQ(error_page::DNS_PROBE_FINISHED_INCONCLUSIVE, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("ERR_NAME_NOT_RESOLVED");
  EXPECT_EQ(0, pending_status_count());
}

// Make sure probes don't run for subframe DNS errors.
IN_PROC_BROWSER_TEST_F(DnsProbeSuccessfulProbesTest, NoProbeInSubframe) {
  NavigateToURL(browser(),
                embedded_test_server()->GetURL("/iframe_dns_error.html"));

  // By the time NavigateToURL returns, the browser will have seen the failed
  // provisional load.  If a probe was started (or considered but not run),
  // then the NetErrorTabHelper would have sent a NetErrorInfo message.  Thus,
  // if one hasn't been sent by now, the NetErrorTabHelper has not (and won't)
  // start a probe for this DNS error.
  EXPECT_EQ(0, pending_status_count());
}

// Make sure browser sends NOT_RUN properly when probes are disabled.
IN_PROC_BROWSER_TEST_F(DnsProbeUnreachableProbesTest, ProbesDisabled) {
  // Disable probes (And corrections).
  browser()->profile()->GetPrefs()->SetBoolean(
      embedder_support::kAlternateErrorPagesEnabled, false);

  NavigateToDnsError();

  EXPECT_EQ(error_page::DNS_PROBE_NOT_RUN, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("ERR_NAME_NOT_RESOLVED");
}

// Test incognito mode. DNS probes should still be enabled.
IN_PROC_BROWSER_TEST_F(DnsProbeFailingProbesTest, Incognito) {
  Browser* incognito = CreateIncognitoBrowser();
  SetActiveBrowser(incognito);

  // Just one commit and one sent status, since the corrections are disabled.
  NavigateToDnsError();
  EXPECT_EQ(error_page::DNS_PROBE_STARTED, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("DNS_PROBE_STARTED");
  EXPECT_EQ(0, pending_status_count());

  StartDelayedProbes(1);

  EXPECT_EQ(error_page::DNS_PROBE_FINISHED_INCONCLUSIVE, WaitForSentStatus());
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingErrorPage("ERR_NAME_NOT_RESOLVED");
}

}  // namespace

}  // namespace chrome_browser_net
