// Copyright 2020 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 "weblayer/test/weblayer_browser_test.h"

#include "base/command_line.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "components/variations/variations_ids_provider.h"
#include "content/public/test/network_connection_change_simulator.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "weblayer/public/navigation.h"
#include "weblayer/public/navigation_controller.h"
#include "weblayer/public/tab.h"
#include "weblayer/shell/browser/shell.h"
#include "weblayer/test/weblayer_browser_test_utils.h"

namespace weblayer {

// The purpose of this test is to verify Variations code is correctly wired up
// for WebLayer. It's not intended to replicate VariationsHttpHeadersBrowserTest
class WebLayerVariationsHttpBrowserTest : public WebLayerBrowserTest {
 public:
  WebLayerVariationsHttpBrowserTest()
      : https_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {}

  ~WebLayerVariationsHttpBrowserTest() override = default;

  void SetUp() override {
    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();

    // HTTPS server only serves a valid cert for localhost, so this is needed to
    // load pages from "www.google.com" without an interstitial.
    command_line->AppendSwitch("ignore-certificate-errors");

    WebLayerBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    auto* variations_provider =
        variations::VariationsIdsProvider::GetInstance();
    variations_provider->ForceVariationIds({"12", "456", "t789"}, "");

    // The test makes requests to google.com which we want to redirect to the
    // test server.
    host_resolver()->AddRule("*", "127.0.0.1");

    https_server_.RegisterRequestHandler(
        base::BindRepeating(&WebLayerVariationsHttpBrowserTest::RequestHandler,
                            base::Unretained(this)));

    ASSERT_TRUE(https_server_.Start());
  }

  GURL GetGoogleUrlWithPath(const std::string& path) const {
    return https_server_.GetURL("www.google.com", path);
  }

  GURL GetGoogleRedirectUrl1() const {
    return GetGoogleUrlWithPath("/redirect");
  }

  GURL GetGoogleRedirectUrl2() const {
    return GetGoogleUrlWithPath("/redirect2");
  }

  GURL GetExampleUrlWithPath(const std::string& path) const {
    return https_server_.GetURL("www.example.com", path);
  }

  GURL GetExampleUrl() const { return GetExampleUrlWithPath("/landing.html"); }

  // Returns whether a given |header| has been received for a |url|. If
  // |url| has not been observed, fails an EXPECT and returns false.
  bool HasReceivedHeader(const GURL& url, const std::string& header) {
    base::AutoLock lock(received_headers_lock_);
    auto it = received_headers_.find(url);
    EXPECT_TRUE(it != received_headers_.end());
    if (it == received_headers_.end())
      return false;
    return it->second.find(header) != it->second.end();
  }

  std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
      const net::test_server::HttpRequest& request) {
    // Retrieve the host name (without port) from the request headers.
    std::string host = "";
    if (request.headers.find("Host") != request.headers.end())
      host = request.headers.find("Host")->second;
    if (host.find(':') != std::string::npos)
      host = host.substr(0, host.find(':'));

    // Recover the original URL of the request by replacing the host name in
    // request.GetURL() (which is 127.0.0.1) with the host name from the request
    // headers.
    GURL::Replacements replacements;
    replacements.SetHostStr(host);
    GURL original_url = request.GetURL().ReplaceComponents(replacements);

    {
      base::AutoLock lock(received_headers_lock_);
      // Memorize the request headers for this URL for later verification.
      received_headers_[original_url] = request.headers;
    }

    // Set up a test server that redirects according to the
    // following redirect chain:
    // https://www.google.com:<port>/redirect
    // --> https://www.google.com:<port>/redirect2
    // --> https://www.example.com:<port>/
    auto http_response =
        std::make_unique<net::test_server::BasicHttpResponse>();
    http_response->AddCustomHeader("Access-Control-Allow-Origin", "*");
    if (request.relative_url == GetGoogleRedirectUrl1().path()) {
      http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
      http_response->AddCustomHeader("Location",
                                     GetGoogleRedirectUrl2().spec());
    } else if (request.relative_url == GetGoogleRedirectUrl2().path()) {
      http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
      http_response->AddCustomHeader("Location", GetExampleUrl().spec());
    } else if (request.relative_url == GetExampleUrl().path()) {
      http_response->set_code(net::HTTP_OK);
      http_response->set_content("hello");
      http_response->set_content_type("text/plain");
    } else {
      return nullptr;
    }
    return http_response;
  }

 protected:
  net::EmbeddedTestServer https_server_;

  base::Lock received_headers_lock_;

  // Stores the observed HTTP Request headers.
  std::map<GURL, net::test_server::HttpRequest::HeaderMap> received_headers_
      GUARDED_BY(received_headers_lock_);
};

// Verify in an integration test that the variations header (X-Client-Data) is
// attached to network requests to Google but stripped on redirects.
IN_PROC_BROWSER_TEST_F(WebLayerVariationsHttpBrowserTest,
                       TestStrippingHeadersFromResourceRequest) {
  OneShotNavigationObserver observer(shell());
  shell()->tab()->GetNavigationController()->Navigate(GetGoogleRedirectUrl1());
  observer.WaitForNavigation();

  EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl1(), "X-Client-Data"));
  EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl2(), "X-Client-Data"));
  EXPECT_TRUE(HasReceivedHeader(GetExampleUrl(), "Host"));
  EXPECT_FALSE(HasReceivedHeader(GetExampleUrl(), "X-Client-Data"));
}

}  // namespace weblayer
