// Copyright 2016 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/page_load_metrics/observers/data_reduction_proxy_metrics_observer.h"

#include <stdint.h>

#include <functional>
#include <memory>
#include <string>

#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "chrome/browser/loader/chrome_navigation_data.h"
#include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
#include "chrome/browser/page_load_metrics/page_load_metrics_observer.h"
#include "chrome/common/page_load_metrics/page_load_timing.h"
#include "chrome/test/base/testing_browser_process.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_data.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_pingback_client.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_page_load_timing.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"

namespace data_reduction_proxy {

namespace {

const char kDefaultTestUrl[] = "http://google.com";

data_reduction_proxy::DataReductionProxyData* DataForNavigationHandle(
    content::WebContents* web_contents,
    content::NavigationHandle* navigation_handle) {
  ChromeNavigationData* chrome_navigation_data = new ChromeNavigationData();
  content::WebContentsTester::For(web_contents)
      ->SetNavigationData(navigation_handle,
                          base::WrapUnique(chrome_navigation_data));
  data_reduction_proxy::DataReductionProxyData* data =
      new data_reduction_proxy::DataReductionProxyData();
  chrome_navigation_data->SetDataReductionProxyData(base::WrapUnique(data));

  return data;
}

// Pingback client responsible for recording the timing information it receives
// from a SendPingback call.
class TestPingbackClient
    : public data_reduction_proxy::DataReductionProxyPingbackClient {
 public:
  TestPingbackClient()
      : data_reduction_proxy::DataReductionProxyPingbackClient(nullptr),
        send_pingback_called_(false) {}
  ~TestPingbackClient() override {}

  void SendPingback(
      const data_reduction_proxy::DataReductionProxyData& data,
      const data_reduction_proxy::DataReductionProxyPageLoadTiming& timing)
      override {
    timing_.reset(
        new data_reduction_proxy::DataReductionProxyPageLoadTiming(timing));
    send_pingback_called_ = true;
    data_ = data.DeepCopy();
  }

  data_reduction_proxy::DataReductionProxyPageLoadTiming* timing() const {
    return timing_.get();
  }

  const data_reduction_proxy::DataReductionProxyData& data() const {
    return *data_;
  }

  bool send_pingback_called() const { return send_pingback_called_; }

  void Reset() {
    send_pingback_called_ = false;
    timing_.reset();
  }

 private:
  std::unique_ptr<data_reduction_proxy::DataReductionProxyPageLoadTiming>
      timing_;
  std::unique_ptr<data_reduction_proxy::DataReductionProxyData> data_;
  bool send_pingback_called_;

  DISALLOW_COPY_AND_ASSIGN(TestPingbackClient);
};

}  // namespace

// DataReductionProxyMetricsObserver responsible for modifying data about the
// navigation in OnCommit. It is also responsible for using a passed in
// DataReductionProxyPingbackClient instead of the default.
class TestDataReductionProxyMetricsObserver
    : public DataReductionProxyMetricsObserver {
 public:
  TestDataReductionProxyMetricsObserver(content::WebContents* web_contents,
                                        TestPingbackClient* pingback_client,
                                        bool data_reduction_proxy_used,
                                        bool lofi_used)
      : web_contents_(web_contents),
        pingback_client_(pingback_client),
        data_reduction_proxy_used_(data_reduction_proxy_used),
        lofi_used_(lofi_used) {}

  ~TestDataReductionProxyMetricsObserver() override {}

  // page_load_metrics::PageLoadMetricsObserver implementation:
  ObservePolicy OnCommit(
      content::NavigationHandle* navigation_handle) override {
    DataReductionProxyData* data =
        DataForNavigationHandle(web_contents_, navigation_handle);
    data->set_used_data_reduction_proxy(data_reduction_proxy_used_);
    data->set_lofi_requested(lofi_used_);
    return DataReductionProxyMetricsObserver::OnCommit(navigation_handle);
  }

  DataReductionProxyPingbackClient* GetPingbackClient() const override {
    return pingback_client_;
  }

 private:
  content::WebContents* web_contents_;
  TestPingbackClient* pingback_client_;
  bool data_reduction_proxy_used_;
  bool lofi_used_;

  DISALLOW_COPY_AND_ASSIGN(TestDataReductionProxyMetricsObserver);
};

class DataReductionProxyMetricsObserverTest
    : public page_load_metrics::PageLoadMetricsObserverTestHarness {
 public:
  DataReductionProxyMetricsObserverTest()
      : pingback_client_(new TestPingbackClient()),
        data_reduction_proxy_used_(false),
        is_using_lofi_(false) {}

  void ResetTest() {
    // Reset to the default testing state. Does not reset histogram state.
    timing_.navigation_start = base::Time::FromDoubleT(1);
    timing_.response_start = base::TimeDelta::FromSeconds(2);
    timing_.parse_start = base::TimeDelta::FromSeconds(3);
    timing_.first_contentful_paint = base::TimeDelta::FromSeconds(4);
    timing_.first_paint = base::TimeDelta::FromSeconds(4);
    timing_.first_meaningful_paint = base::TimeDelta::FromSeconds(8);
    timing_.first_image_paint = base::TimeDelta::FromSeconds(5);
    timing_.first_text_paint = base::TimeDelta::FromSeconds(6);
    timing_.load_event_start = base::TimeDelta::FromSeconds(7);
    timing_.parse_stop = base::TimeDelta::FromSeconds(4);
    timing_.parse_blocked_on_script_load_duration =
        base::TimeDelta::FromSeconds(1);
    PopulateRequiredTimingFields(&timing_);
  }

  void RunTest(bool data_reduction_proxy_used, bool is_using_lofi) {
    data_reduction_proxy_used_ = data_reduction_proxy_used;
    is_using_lofi_ = is_using_lofi;
    NavigateAndCommit(GURL(kDefaultTestUrl));
    SimulateTimingUpdate(timing_);
    pingback_client_->Reset();
  }

  void RunTestAndNavigateToUntrackedUrl(bool data_reduction_proxy_used,
                                        bool is_using_lofi) {
    RunTest(data_reduction_proxy_used, is_using_lofi);
    NavigateToUntrackedUrl();
  }

  // Verify that, if expected and actual are set, their values are equal.
  // Otherwise, verify that both are unset.
  void ExpectEqualOrUnset(const base::Optional<base::TimeDelta>& expected,
                          const base::Optional<base::TimeDelta>& actual) {
    if (expected && actual) {
      EXPECT_EQ(expected.value(), actual.value());
    } else {
      EXPECT_TRUE(!expected);
      EXPECT_TRUE(!actual);
    }
  }

  void ValidateTimes() {
    EXPECT_TRUE(pingback_client_->send_pingback_called());
    EXPECT_EQ(timing_.navigation_start,
              pingback_client_->timing()->navigation_start);
    ExpectEqualOrUnset(timing_.first_contentful_paint,
              pingback_client_->timing()->first_contentful_paint);
    ExpectEqualOrUnset(
        timing_.first_meaningful_paint,
        pingback_client_->timing()->experimental_first_meaningful_paint);
    ExpectEqualOrUnset(timing_.response_start,
              pingback_client_->timing()->response_start);
    ExpectEqualOrUnset(timing_.load_event_start,
              pingback_client_->timing()->load_event_start);
    ExpectEqualOrUnset(timing_.first_image_paint,
              pingback_client_->timing()->first_image_paint);
  }

  void ValidateLoFiInPingback(bool lofi_expected) {
    EXPECT_TRUE(pingback_client_->send_pingback_called());
    EXPECT_EQ(lofi_expected, pingback_client_->data().lofi_received());
  }

  void ValidateHistograms() {
    ValidateHistogramsForSuffix(
        internal::kHistogramDOMContentLoadedEventFiredSuffix,
        timing_.dom_content_loaded_event_start);
    ValidateHistogramsForSuffix(internal::kHistogramFirstLayoutSuffix,
                                timing_.first_layout);
    ValidateHistogramsForSuffix(internal::kHistogramLoadEventFiredSuffix,
                                timing_.load_event_start);
    ValidateHistogramsForSuffix(internal::kHistogramFirstContentfulPaintSuffix,
                                timing_.first_contentful_paint);
    ValidateHistogramsForSuffix(internal::kHistogramFirstMeaningfulPaintSuffix,
                                timing_.first_meaningful_paint);
    ValidateHistogramsForSuffix(internal::kHistogramFirstImagePaintSuffix,
                                timing_.first_image_paint);
    ValidateHistogramsForSuffix(internal::kHistogramFirstPaintSuffix,
                                timing_.first_paint);
    ValidateHistogramsForSuffix(internal::kHistogramFirstTextPaintSuffix,
                                timing_.first_text_paint);
    ValidateHistogramsForSuffix(internal::kHistogramParseStartSuffix,
                                timing_.parse_start);
    ValidateHistogramsForSuffix(
        internal::kHistogramParseBlockedOnScriptLoadSuffix,
        timing_.parse_blocked_on_script_load_duration);
    ValidateHistogramsForSuffix(
        internal::kHistogramParseDurationSuffix,
        timing_.parse_stop.value() - timing_.parse_start.value());
  }

  void ValidateHistogramsForSuffix(
      const std::string& histogram_suffix,
      const base::Optional<base::TimeDelta>& event) {
    histogram_tester().ExpectTotalCount(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(histogram_suffix),
        data_reduction_proxy_used_ ? 1 : 0);
    histogram_tester().ExpectTotalCount(
        std::string(internal::kHistogramDataReductionProxyLoFiOnPrefix)
            .append(histogram_suffix),
        is_using_lofi_ ? 1 : 0);
    if (!data_reduction_proxy_used_)
      return;
    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(histogram_suffix),
        static_cast<base::HistogramBase::Sample>(
            event.value().InMilliseconds()),
        1);
    if (!is_using_lofi_)
      return;
    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyLoFiOnPrefix)
            .append(histogram_suffix),
        event.value().InMilliseconds(), is_using_lofi_ ? 1 : 0);
  }

  void ValidateDataHistograms(int network_resources,
                              int drp_resources,
                              int64_t network_bytes,
                              int64_t drp_bytes,
                              int64_t ocl_bytes) {
    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(internal::kResourcesPercentProxied),
        100 * drp_resources / network_resources, 1);

    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(internal::kBytesPercentProxied),
        static_cast<int>(100 * drp_bytes / network_bytes), 1);

    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(internal::kNetworkResources),
        network_resources, 1);

    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(internal::kResourcesProxied),
        drp_resources, 1);

    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(internal::kResourcesNotProxied),
        network_resources - drp_resources, 1);

    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(internal::kNetworkBytes),
        static_cast<int>(network_bytes / 1024), 1);

    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(internal::kBytesProxied),
        static_cast<int>(drp_bytes / 1024), 1);

    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(internal::kBytesNotProxied),
        static_cast<int>((network_bytes - drp_bytes) / 1024), 1);

    histogram_tester().ExpectUniqueSample(
        std::string(internal::kHistogramDataReductionProxyPrefix)
            .append(internal::kBytesOriginal),
        static_cast<int>(ocl_bytes / 1024), 1);
    if (ocl_bytes < network_bytes) {
      histogram_tester().ExpectUniqueSample(
          std::string(internal::kHistogramDataReductionProxyPrefix)
              .append(internal::kBytesInflationPercent),
          static_cast<int>(100 * network_bytes / ocl_bytes - 100), 1);

      histogram_tester().ExpectUniqueSample(
          std::string(internal::kHistogramDataReductionProxyPrefix)
              .append(internal::kBytesInflation),
          static_cast<int>((network_bytes - ocl_bytes) / 1024), 1);
    } else {
      histogram_tester().ExpectUniqueSample(
          std::string(internal::kHistogramDataReductionProxyPrefix)
              .append(internal::kBytesCompressionRatio),
          static_cast<int>(100 * network_bytes / ocl_bytes), 1);

      histogram_tester().ExpectUniqueSample(
          std::string(internal::kHistogramDataReductionProxyPrefix)
              .append(internal::kBytesSavings),
          static_cast<int>((ocl_bytes - network_bytes) / 1024), 1);
    }
  }

 protected:
  void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override {
    tracker->AddObserver(
        base::MakeUnique<TestDataReductionProxyMetricsObserver>(
            web_contents(), pingback_client_.get(), data_reduction_proxy_used_,
            is_using_lofi_));
  }

  std::unique_ptr<TestPingbackClient> pingback_client_;
  page_load_metrics::PageLoadTiming timing_;

 private:
  bool data_reduction_proxy_used_;
  bool is_using_lofi_;

  DISALLOW_COPY_AND_ASSIGN(DataReductionProxyMetricsObserverTest);
};

TEST_F(DataReductionProxyMetricsObserverTest, DataReductionProxyOff) {
  ResetTest();
  // Verify that when the data reduction proxy was not used, no UMA is reported.
  RunTest(false, false);
  ValidateHistograms();
}

TEST_F(DataReductionProxyMetricsObserverTest, DataReductionProxyOn) {
  ResetTest();
  // Verify that when the data reduction proxy was used, but lofi was not used,
  // the correpsonding UMA is reported.
  RunTest(true, false);
  ValidateHistograms();
}

TEST_F(DataReductionProxyMetricsObserverTest, LofiEnabled) {
  ResetTest();
  // Verify that when the data reduction proxy was used and lofi was used, both
  // histograms are reported.
  RunTest(true, true);
  ValidateHistograms();
}

TEST_F(DataReductionProxyMetricsObserverTest, OnCompletePingback) {
  ResetTest();
  // Verify that when data reduction proxy was used the correct timing
  // information is sent to SendPingback.
  RunTestAndNavigateToUntrackedUrl(true, false);
  ValidateTimes();

  ResetTest();
  // Verify that when data reduction proxy was used but first image paint is
  // unset, the correct timing information is sent to SendPingback.
  timing_.first_image_paint = base::nullopt;
  RunTestAndNavigateToUntrackedUrl(true, false);
  ValidateTimes();

  ResetTest();
  // Verify that when data reduction proxy was used but first contentful paint
  // is unset, SendPingback is not called.
  timing_.first_contentful_paint = base::nullopt;
  RunTestAndNavigateToUntrackedUrl(true, false);
  ValidateTimes();

  ResetTest();
  // Verify that when data reduction proxy was used but first meaningful paint
  // is unset, SendPingback is not called.
  timing_.first_meaningful_paint = base::nullopt;
  RunTestAndNavigateToUntrackedUrl(true, false);
  ValidateTimes();

  ResetTest();
  // Verify that when data reduction proxy was used but load event start is
  // unset, SendPingback is not called.
  timing_.load_event_start = base::nullopt;
  RunTestAndNavigateToUntrackedUrl(true, false);
  ValidateTimes();
  ValidateLoFiInPingback(false);

  ResetTest();

  std::unique_ptr<DataReductionProxyData> data =
      base::MakeUnique<DataReductionProxyData>();
  data->set_used_data_reduction_proxy(true);
  data->set_lofi_received(true);

  // Verify LoFi is tracked when a LoFi response is received.
  page_load_metrics::ExtraRequestInfo resource = {
      true /*was_cached*/, 1024 * 40 /* raw_body_bytes */,
      0 /* original_network_content_length */, std::move(data)};

  RunTest(true, false);
  SimulateLoadedResource(resource);
  NavigateToUntrackedUrl();
  ValidateTimes();
  ValidateLoFiInPingback(true);

  ResetTest();
  // Verify that when data reduction proxy was not used, SendPingback is not
  // called.
  RunTestAndNavigateToUntrackedUrl(false, false);
  EXPECT_FALSE(pingback_client_->send_pingback_called());

  ResetTest();
  // Verify that when the holdback experiment is enabled, no pingback is sent.
  base::FieldTrialList field_trial_list(nullptr);
  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
      "DataCompressionProxyHoldback", "Enabled"));
  RunTestAndNavigateToUntrackedUrl(true, false);
  EXPECT_FALSE(pingback_client_->send_pingback_called());
}

TEST_F(DataReductionProxyMetricsObserverTest, ByteInformationCompression) {
  ResetTest();

  RunTest(true, false);

  std::unique_ptr<DataReductionProxyData> data =
      base::MakeUnique<DataReductionProxyData>();
  data->set_used_data_reduction_proxy(true);

  // Prepare 4 resources of varying size and configurations.
  page_load_metrics::ExtraRequestInfo resources[] = {
      // Cached request.
      {true /*was_cached*/, 1024 * 40 /* raw_body_bytes */,
       0 /* original_network_content_length */,
       nullptr /* data_reduction_proxy_data */},
      // Uncached non-proxied request.
      {false /*was_cached*/, 1024 * 40 /* raw_body_bytes */,
       1024 * 40 /* original_network_content_length */,
       nullptr /* data_reduction_proxy_data */},
      // Uncached proxied request with .1 compression ratio.
      {false /*was_cached*/, 1024 * 40 /* raw_body_bytes */,
       1024 * 40 * 10 /* original_network_content_length */, data->DeepCopy()},
      // Uncached proxied request with .5 compression ratio.
      {false /*was_cached*/, 1024 * 40 /* raw_body_bytes */,
       1024 * 40 * 5 /* original_network_content_length */, std::move(data)},
  };

  int network_resources = 0;
  int drp_resources = 0;
  int64_t network_bytes = 0;
  int64_t drp_bytes = 0;
  int64_t ocl_bytes = 0;
  for (const auto& request : resources) {
    SimulateLoadedResource(request);
    if (!request.was_cached) {
      network_bytes += request.raw_body_bytes;
      ocl_bytes += request.original_network_content_length;
      ++network_resources;
    }
    if (request.data_reduction_proxy_data &&
        request.data_reduction_proxy_data->used_data_reduction_proxy()) {
      drp_bytes += request.raw_body_bytes;
      ++drp_resources;
    }
  }

  NavigateToUntrackedUrl();

  ValidateDataHistograms(network_resources, drp_resources, network_bytes,
                         drp_bytes, ocl_bytes);
}

TEST_F(DataReductionProxyMetricsObserverTest, ByteInformationInflation) {
  ResetTest();

  RunTest(true, false);

  std::unique_ptr<DataReductionProxyData> data =
      base::MakeUnique<DataReductionProxyData>();
  data->set_used_data_reduction_proxy(true);

  // Prepare 4 resources of varying size and configurations.
  page_load_metrics::ExtraRequestInfo resources[] = {
      // Cached request.
      {true /*was_cached*/, 1024 * 40 /* raw_body_bytes */,
       0 /* original_network_content_length */,
       nullptr /* data_reduction_proxy_data */},
      // Uncached non-proxied request.
      {false /*was_cached*/, 1024 * 40 /* raw_body_bytes */,
       1024 * 40 /* original_network_content_length */,
       nullptr /* data_reduction_proxy_data */},
      // Uncached proxied request with .1 compression ratio.
      {false /*was_cached*/, 1024 * 40 * 10 /* raw_body_bytes */,
       1024 * 40 /* original_network_content_length */, data->DeepCopy()},
      // Uncached proxied request with .5 compression ratio.
      {false /*was_cached*/, 1024 * 40 * 5 /* raw_body_bytes */,
       1024 * 40 /* original_network_content_length */, std::move(data)},
  };

  int network_resources = 0;
  int drp_resources = 0;
  int64_t network_bytes = 0;
  int64_t drp_bytes = 0;
  int64_t ocl_bytes = 0;
  for (const auto& request : resources) {
    SimulateLoadedResource(request);
    if (!request.was_cached) {
      network_bytes += request.raw_body_bytes;
      ocl_bytes += request.original_network_content_length;
      ++network_resources;
    }
    if (request.data_reduction_proxy_data &&
        request.data_reduction_proxy_data->used_data_reduction_proxy()) {
      drp_bytes += request.raw_body_bytes;
      ++drp_resources;
    }
  }

  NavigateToUntrackedUrl();

  ValidateDataHistograms(network_resources, drp_resources, network_bytes,
                         drp_bytes, ocl_bytes);
}

}  //  namespace data_reduction_proxy
