// Copyright 2017 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 "components/data_reduction_proxy/content/browser/content_resource_type_provider.h"

#include "base/command_line.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/previews_state.h"
#include "net/socket/socket_test_util.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace data_reduction_proxy {

namespace {

#if defined(OS_ANDROID)
const Client kClient = Client::CHROME_ANDROID;
#elif defined(OS_IOS)
const Client kClient = Client::CHROME_IOS;
#elif defined(OS_MACOSX)
const Client kClient = Client::CHROME_MAC;
#elif defined(OS_CHROMEOS)
const Client kClient = Client::CHROME_CHROMEOS;
#elif defined(OS_LINUX)
const Client kClient = Client::CHROME_LINUX;
#elif defined(OS_WIN)
const Client kClient = Client::CHROME_WINDOWS;
#elif defined(OS_FREEBSD)
const Client kClient = Client::CHROME_FREEBSD;
#elif defined(OS_OPENBSD)
const Client kClient = Client::CHROME_OPENBSD;
#elif defined(OS_SOLARIS)
const Client kClient = Client::CHROME_SOLARIS;
#elif defined(OS_QNX)
const Client kClient = Client::CHROME_QNX;
#else
const Client kClient = Client::UNKNOWN;
#endif

const std::string kBody = "response body";

}  // namespace

class ContentResourceProviderTest : public testing::Test {
 public:
  ContentResourceProviderTest()
      : context_(true), content_resource_type_provider_(nullptr) {}

  void Init(const std::vector<DataReductionProxyServer> proxy_servers) {
    test_context_ = DataReductionProxyTestContext::Builder()
                        .WithClient(kClient)
                        .WithProxiesForHttp(proxy_servers)
                        .WithURLRequestContext(&context_)
                        .WithMockClientSocketFactory(&mock_socket_factory_)
                        .Build();

    data_reduction_proxy_network_delegate_.reset(
        new DataReductionProxyNetworkDelegate(
            std::unique_ptr<net::NetworkDelegate>(
                new net::NetworkDelegateImpl()),
            test_context_->config(),
            test_context_->io_data()->request_options(),
            test_context_->configurator()));

    data_reduction_proxy_network_delegate_->InitIODataAndUMA(
        test_context_->io_data(), test_context_->io_data()->bypass_stats());

    context_.set_client_socket_factory(&mock_socket_factory_);
    context_.set_network_delegate(data_reduction_proxy_network_delegate_.get());
    context_.set_proxy_delegate(test_context_->io_data()->proxy_delegate());
    context_.Init();

    test_context_->DisableWarmupURLFetch();
    test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess();

    std::unique_ptr<data_reduction_proxy::ContentResourceTypeProvider>
        content_resource_type_provider(
            new data_reduction_proxy::ContentResourceTypeProvider());
    content_resource_type_provider_ = content_resource_type_provider.get();
    test_context_->io_data()->set_resource_type_provider(
        std::move(content_resource_type_provider));
  }

  void AllocateRequestInfoForTesting(net::URLRequest* request,
                                     content::ResourceType resource_type) {
    content::ResourceRequestInfo::AllocateForTesting(
        request, resource_type, nullptr, -1, -1, -1,
        resource_type == content::RESOURCE_TYPE_MAIN_FRAME,
        false,  // allow_download
        false,  // is_async
        content::PREVIEWS_OFF,
        nullptr);  // navigation_ui_data
  }

  std::unique_ptr<net::URLRequest> CreateRequestByType(
      const GURL& gurl,
      content::ResourceType resource_type) {
    std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
        gurl, net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS);
    AllocateRequestInfoForTesting(request.get(), resource_type);
    return request;
  }

  ResourceTypeProvider* content_resource_type_provider() const {
    return content_resource_type_provider_;
  }

  net::MockClientSocketFactory* mock_socket_factory() {
    return &mock_socket_factory_;
  }

 protected:
  base::MessageLoopForIO message_loop_;
  net::TestURLRequestContext context_;
  net::MockClientSocketFactory mock_socket_factory_;
  net::TestDelegate delegate_;
  std::unique_ptr<DataReductionProxyTestContext> test_context_;
  std::unique_ptr<DataReductionProxyNetworkDelegate>
      data_reduction_proxy_network_delegate_;
  ResourceTypeProvider* content_resource_type_provider_;
};

// Tests that the correct data reduction proxy is used based on the resource
// content type.
TEST_F(ContentResourceProviderTest, VerifyCorrectProxyUsed) {
  std::vector<DataReductionProxyServer> proxies_for_http;

  net::ProxyServer core_primary = net::ProxyServer::FromURI(
      "http://origin.net:80", net::ProxyServer::SCHEME_HTTP);
  net::ProxyServer core_fallback = net::ProxyServer::FromURI(
      "http://fallback.net:80", net::ProxyServer::SCHEME_HTTP);

  proxies_for_http.push_back(
      DataReductionProxyServer(core_primary, ProxyServer_ProxyType_CORE));
  proxies_for_http.push_back(
      DataReductionProxyServer(core_fallback, ProxyServer_ProxyType_CORE));
  Init(proxies_for_http);

  const struct {
    GURL gurl;
    content::ResourceType resource_type;
    ResourceTypeProvider::ContentType expected_content_type;
  } tests[] = {
      {GURL("http://www.google.com/main-frame"),
       content::RESOURCE_TYPE_MAIN_FRAME,
       ResourceTypeProvider::CONTENT_TYPE_MAIN_FRAME},
      {GURL("http://www.google.com/sub-frame"),
       content::RESOURCE_TYPE_SUB_FRAME,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/stylesheet"),
       content::RESOURCE_TYPE_STYLESHEET,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/script"), content::RESOURCE_TYPE_SCRIPT,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/image"), content::RESOURCE_TYPE_IMAGE,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/font"), content::RESOURCE_TYPE_FONT_RESOURCE,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/sub-resource"),
       content::RESOURCE_TYPE_SUB_RESOURCE,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/object"), content::RESOURCE_TYPE_OBJECT,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/media"), content::RESOURCE_TYPE_MEDIA,
       ResourceTypeProvider::CONTENT_TYPE_MEDIA},
      {GURL("http://www.google.com/worker"), content::RESOURCE_TYPE_WORKER,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/shared-worker"),
       content::RESOURCE_TYPE_SHARED_WORKER,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN}};

  for (const auto test : tests) {
    net::MockRead mock_reads[] = {
        net::MockRead(
            "HTTP/1.1 200 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
        net::MockRead(kBody.c_str()), net::MockRead(net::SYNCHRONOUS, net::OK),
    };
    net::StaticSocketDataProvider socket_data_provider(
        mock_reads, base::span<net::MockWrite>());
    mock_socket_factory()->AddSocketDataProvider(&socket_data_provider);

    base::HistogramTester histogram_tester;
    std::unique_ptr<net::URLRequest> request =
        CreateRequestByType(test.gurl, test.resource_type);
    request->Start();
    base::RunLoop().RunUntilIdle();

    EXPECT_EQ(test.expected_content_type,
              content_resource_type_provider()->GetContentType(request->url()));

    // Querying for the content type of |request->url()| again should still
    // give the correct result.
    EXPECT_EQ(test.expected_content_type,
              content_resource_type_provider()->GetContentType(request->url()));

    EXPECT_EQ(core_primary, request->proxy_server());
  }
}

// Tests that the resource content type was correctly computed, and was
// available to the data reduction proxy delegate.
TEST_F(ContentResourceProviderTest, SetAndGetContentResourceTypeContent) {
  std::vector<DataReductionProxyServer> proxies_for_http;

  net::ProxyServer unspecified = net::ProxyServer::FromURI(
      "http://origin.net:80", net::ProxyServer::SCHEME_HTTP);
  net::ProxyServer core = net::ProxyServer::FromURI(
      "http://fallback.net:80", net::ProxyServer::SCHEME_HTTP);

  proxies_for_http.push_back(DataReductionProxyServer(
      unspecified, ProxyServer_ProxyType_UNSPECIFIED_TYPE));
  proxies_for_http.push_back(
      DataReductionProxyServer(core, ProxyServer_ProxyType_CORE));
  Init(proxies_for_http);

  const struct {
    GURL gurl;
    content::ResourceType resource_type;
    ResourceTypeProvider::ContentType expected_content_type;
  } tests[] = {
      {GURL("http://www.google.com/main-frame"),
       content::RESOURCE_TYPE_MAIN_FRAME,
       ResourceTypeProvider::CONTENT_TYPE_MAIN_FRAME},
      {GURL("http://www.google.com/sub-frame"),
       content::RESOURCE_TYPE_SUB_FRAME,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/stylesheet"),
       content::RESOURCE_TYPE_STYLESHEET,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/script"), content::RESOURCE_TYPE_SCRIPT,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/image"), content::RESOURCE_TYPE_IMAGE,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/font"), content::RESOURCE_TYPE_FONT_RESOURCE,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/sub-resource"),
       content::RESOURCE_TYPE_SUB_RESOURCE,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/object"), content::RESOURCE_TYPE_OBJECT,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/media"), content::RESOURCE_TYPE_MEDIA,
       ResourceTypeProvider::CONTENT_TYPE_MEDIA},
      {GURL("http://www.google.com/worker"), content::RESOURCE_TYPE_WORKER,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/shared-worker"),
       content::RESOURCE_TYPE_SHARED_WORKER,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN}};

  for (const auto test : tests) {
    net::MockRead mock_reads[] = {
        net::MockRead(
            "HTTP/1.1 200 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
        net::MockRead(kBody.c_str()), net::MockRead(net::SYNCHRONOUS, net::OK),
    };
    net::StaticSocketDataProvider socket_data_provider(
        mock_reads, base::span<net::MockWrite>());
    mock_socket_factory()->AddSocketDataProvider(&socket_data_provider);

    base::HistogramTester histogram_tester;
    std::unique_ptr<net::URLRequest> request =
        CreateRequestByType(test.gurl, test.resource_type);
    request->Start();
    base::RunLoop().RunUntilIdle();

    EXPECT_EQ(test.expected_content_type,
              content_resource_type_provider()->GetContentType(request->url()));

    // Querying for the content type of |request->url()| again should still
    // give the correct result.
    EXPECT_EQ(test.expected_content_type,
              content_resource_type_provider()->GetContentType(request->url()));

    if (test.expected_content_type ==
        ResourceTypeProvider::CONTENT_TYPE_MEDIA) {
      EXPECT_EQ(core, request->proxy_server());
    } else {
      EXPECT_EQ(unspecified, request->proxy_server());
    }
  }
}

// Tests that the request is fetched directly if no valid data reduction
// proxy is available.
TEST_F(ContentResourceProviderTest, FetchDirect) {
  std::vector<DataReductionProxyServer> proxies_for_http;

  net::ProxyServer unspecified = net::ProxyServer::FromURI(
      "http://origin.net:80", net::ProxyServer::SCHEME_HTTP);
  net::ProxyServer core = net::ProxyServer::FromURI(
      "http://fallback.net:80", net::ProxyServer::SCHEME_HTTP);

  proxies_for_http.push_back(DataReductionProxyServer(
      unspecified, ProxyServer_ProxyType_UNSPECIFIED_TYPE));
  proxies_for_http.push_back(
      DataReductionProxyServer(core, ProxyServer_ProxyType_UNSPECIFIED_TYPE));
  Init(proxies_for_http);

  const struct {
    GURL gurl;
    content::ResourceType resource_type;
    ResourceTypeProvider::ContentType expected_content_type;
  } tests[] = {
      {GURL("http://www.google.com/main-frame"),
       content::RESOURCE_TYPE_MAIN_FRAME,
       ResourceTypeProvider::CONTENT_TYPE_MAIN_FRAME},
      {GURL("http://www.google.com/sub-frame"),
       content::RESOURCE_TYPE_SUB_FRAME,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/stylesheet"),
       content::RESOURCE_TYPE_STYLESHEET,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/script"), content::RESOURCE_TYPE_SCRIPT,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/image"), content::RESOURCE_TYPE_IMAGE,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/font"), content::RESOURCE_TYPE_FONT_RESOURCE,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/sub-resource"),
       content::RESOURCE_TYPE_SUB_RESOURCE,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/object"), content::RESOURCE_TYPE_OBJECT,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/media"), content::RESOURCE_TYPE_MEDIA,
       ResourceTypeProvider::CONTENT_TYPE_MEDIA},
      {GURL("http://www.google.com/worker"), content::RESOURCE_TYPE_WORKER,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN},
      {GURL("http://www.google.com/shared-worker"),
       content::RESOURCE_TYPE_SHARED_WORKER,
       ResourceTypeProvider::CONTENT_TYPE_UNKNOWN}};

  for (const auto test : tests) {
    net::MockRead mock_reads[] = {
        net::MockRead(
            "HTTP/1.1 200 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
        net::MockRead(kBody.c_str()), net::MockRead(net::SYNCHRONOUS, net::OK),
    };
    net::StaticSocketDataProvider socket_data_provider(
        mock_reads, base::span<net::MockWrite>());
    mock_socket_factory()->AddSocketDataProvider(&socket_data_provider);

    base::HistogramTester histogram_tester;
    std::unique_ptr<net::URLRequest> request =
        CreateRequestByType(test.gurl, test.resource_type);
    request->Start();
    base::RunLoop().RunUntilIdle();

    EXPECT_EQ(test.expected_content_type,
              content_resource_type_provider()->GetContentType(request->url()));

    // Querying for the content type of |request->url()| again should still
    // give the correct result.
    EXPECT_EQ(test.expected_content_type,
              content_resource_type_provider()->GetContentType(request->url()));

    if (test.expected_content_type ==
        ResourceTypeProvider::CONTENT_TYPE_MEDIA) {
      EXPECT_EQ(net::ProxyServer::Direct(), request->proxy_server());
    } else {
      EXPECT_EQ(unspecified, request->proxy_server());
    }
  }
}

}  // namespace data_reduction_proxy
