// Copyright (c) 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 <string>

#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/net/profile_network_context_service.h"
#include "chrome/browser/net/profile_network_context_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/prefs/pref_service.h"
#include "components/proxy_config/proxy_config_dictionary.h"
#include "components/proxy_config/proxy_config_pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_test_utils.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "url/gurl.h"

// This file tests that net::LoadTimingInfo is correctly hooked up to the
// NavigationTiming API.  It depends on behavior in a large number of files
// spread across multiple projects, so is somewhat arbitrarily put in
// chrome/browser/net.

namespace {

// Structure used for retrieved from the renderer process.
// These are milliseconds after fetch start, or -1 if not
// present
struct TimingDeltas {
  int dns_start;
  int dns_end;
  int connect_start;
  int ssl_start;
  int connect_end;
  int send_start;
  // Must be non-negative and greater than all other times.
  int receive_headers_end;
};

class LoadTimingBrowserTest : public InProcessBrowserTest {
 public:
  LoadTimingBrowserTest() {
  }

  ~LoadTimingBrowserTest() override {}

  // Reads applicable times from performance.timing and writes them to
  // |navigation_deltas|.  Proxy times and send end cannot be read from the
  // Navigation Timing API, so those are all left as null.
  void GetResultDeltas(TimingDeltas* navigation_deltas) {
    *navigation_deltas = TimingDeltas();
    navigation_deltas->dns_start = GetResultDelta("domainLookupStart");
    navigation_deltas->dns_end = GetResultDelta("domainLookupEnd");
    navigation_deltas->connect_start = GetResultDelta("connectStart");
    navigation_deltas->connect_end = GetResultDelta("connectEnd");
    navigation_deltas->send_start = GetResultDelta("requestStart");
    navigation_deltas->receive_headers_end = GetResultDelta("responseStart");

    // Unlike the above times, secureConnectionStart will be zero when not
    // applicable.  In that case, leave ssl_start as null.
    bool ssl_start_zero = false;
    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
                    browser()->tab_strip_model()->GetActiveWebContents(),
                    "window.domAutomationController.send("
                        "performance.timing.secureConnectionStart == 0);",
                    &ssl_start_zero));
    if (!ssl_start_zero)
      navigation_deltas->ssl_start = GetResultDelta("secureConnectionStart");
    else
      navigation_deltas->ssl_start = -1;

    // Simple sanity checks.  Make sure times that correspond to LoadTimingInfo
    // occur between fetchStart and loadEventEnd.  Relationships between
    // intervening times are handled by the test bodies.
    int fetch_start = GetResultDelta("fetchStart");
    // While the input dns_start is sometimes null, when read from the
    // NavigationTiming API, it's always non-null.
    EXPECT_LE(fetch_start, navigation_deltas->dns_start);

    int load_event_end = GetResultDelta("loadEventEnd");
    EXPECT_LE(navigation_deltas->receive_headers_end, load_event_end);
  }

  // Returns the time between performance.timing.fetchStart and the time with
  // the specified name.  This time must be non-negative.
  int GetResultDelta(const std::string& name) {
    int time_ms = 0;
    std::string command(base::StringPrintf(
        "window.domAutomationController.send("
            "performance.timing.%s - performance.timing.fetchStart);",
        name.c_str()));
    EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
                    browser()->tab_strip_model()->GetActiveWebContents(),
                    command.c_str(),
                    &time_ms));
    // Basic sanity check.
    EXPECT_GE(time_ms, 0);
    return time_ms;
  }
};

IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, HTTP) {
  ASSERT_TRUE(spawned_test_server()->Start());
  GURL url = spawned_test_server()->GetURL("chunked?waitBeforeHeaders=100");
  ui_test_utils::NavigateToURL(browser(), url);

  TimingDeltas navigation_deltas;
  GetResultDeltas(&navigation_deltas);

  EXPECT_LE(navigation_deltas.dns_start, navigation_deltas.dns_end);
  EXPECT_LE(navigation_deltas.dns_end, navigation_deltas.connect_start);
  EXPECT_LE(navigation_deltas.connect_start, navigation_deltas.connect_end);
  EXPECT_LE(navigation_deltas.connect_end, navigation_deltas.send_start);
  EXPECT_LT(navigation_deltas.send_start,
            navigation_deltas.receive_headers_end);

  EXPECT_EQ(navigation_deltas.ssl_start, -1);
}

IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, HTTPS) {
  net::SpawnedTestServer https_server(net::SpawnedTestServer::TYPE_HTTPS,
                                      net::BaseTestServer::SSLOptions(),
                                      base::FilePath());
  ASSERT_TRUE(https_server.Start());
  GURL url = https_server.GetURL("chunked?waitBeforeHeaders=100");
  ui_test_utils::NavigateToURL(browser(), url);

  TimingDeltas navigation_deltas;
  GetResultDeltas(&navigation_deltas);

  EXPECT_LE(navigation_deltas.dns_start, navigation_deltas.dns_end);
  EXPECT_LE(navigation_deltas.dns_end, navigation_deltas.connect_start);
  EXPECT_LE(navigation_deltas.connect_start, navigation_deltas.ssl_start);
  EXPECT_LE(navigation_deltas.ssl_start, navigation_deltas.connect_end);
  EXPECT_LE(navigation_deltas.connect_end, navigation_deltas.send_start);
  EXPECT_LT(navigation_deltas.send_start,
            navigation_deltas.receive_headers_end);
}

IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, Proxy) {
  ASSERT_TRUE(spawned_test_server()->Start());

  browser()->profile()->GetPrefs()->Set(
      proxy_config::prefs::kProxy,
      *ProxyConfigDictionary::CreateFixedServers(
          spawned_test_server()->host_port_pair().ToString(), std::string()));
  ProfileNetworkContextServiceFactory::GetForContext(browser()->profile())
      ->FlushProxyConfigMonitorForTesting();

  GURL url = spawned_test_server()->GetURL("chunked?waitBeforeHeaders=100");
  ui_test_utils::NavigateToURL(browser(), url);

  TimingDeltas navigation_deltas;
  GetResultDeltas(&navigation_deltas);

  EXPECT_LE(navigation_deltas.dns_start, navigation_deltas.dns_end);
  EXPECT_LE(navigation_deltas.dns_end, navigation_deltas.connect_start);
  EXPECT_LE(navigation_deltas.connect_start, navigation_deltas.connect_end);
  EXPECT_LE(navigation_deltas.connect_end, navigation_deltas.send_start);
  EXPECT_LT(navigation_deltas.send_start,
            navigation_deltas.receive_headers_end);

  EXPECT_EQ(navigation_deltas.ssl_start, -1);
}

IN_PROC_BROWSER_TEST_F(LoadTimingBrowserTest, FTP) {
  net::SpawnedTestServer ftp_server(net::SpawnedTestServer::TYPE_FTP,
                                    base::FilePath());
  ASSERT_TRUE(ftp_server.Start());
  GURL url = ftp_server.GetURL("/");
  ui_test_utils::NavigateToURL(browser(), url);

  TimingDeltas navigation_deltas;
  GetResultDeltas(&navigation_deltas);

  EXPECT_EQ(navigation_deltas.dns_start, 0);
  EXPECT_EQ(navigation_deltas.dns_end, 0);
  EXPECT_EQ(navigation_deltas.connect_start, 0);
  EXPECT_EQ(navigation_deltas.connect_end, 0);
  EXPECT_EQ(navigation_deltas.receive_headers_end, 0);
  EXPECT_EQ(navigation_deltas.ssl_start, -1);
}

}  // namespace
