// Copyright 2019 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 "content/test/resource_load_observer.h"

#include <string>
#include <vector>

#include "base/path_service.h"
#include "base/run_loop.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_paths.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

ResourceLoadObserver::ResourceLoadObserver(Shell* shell)
    : WebContentsObserver(shell->web_contents()) {}

ResourceLoadObserver::~ResourceLoadObserver() = default;

// Use this method with the SCOPED_TRACE macro, so it shows the caller context
// if it fails.
void ResourceLoadObserver::CheckResourceLoaded(
    const GURL& original_url,
    const GURL& referrer,
    const std::string& load_method,
    network::mojom::RequestDestination request_destination,
    const base::FilePath::StringPieceType& served_file_name,
    const std::string& mime_type,
    const std::string& ip_address,
    bool was_cached,
    bool first_network_request,
    const base::TimeTicks& before_request,
    const base::TimeTicks& after_request) {
  bool resource_load_info_found = false;
  for (const auto& resource_load_info : resource_load_infos_) {
    if (resource_load_info->original_url != original_url)
      continue;

    resource_load_info_found = true;
    int64_t file_size = -1;
    if (!served_file_name.empty()) {
      base::ScopedAllowBlockingForTesting allow_blocking;
      base::FilePath test_dir;
      ASSERT_TRUE(base::PathService::Get(content::DIR_TEST_DATA, &test_dir));
      base::FilePath served_file = test_dir.Append(served_file_name);
      ASSERT_TRUE(GetFileSize(served_file, &file_size));
    }
    EXPECT_EQ(referrer, resource_load_info->referrer);
    EXPECT_EQ(load_method, resource_load_info->method);
    EXPECT_EQ(request_destination, resource_load_info->request_destination);
    if (!first_network_request)
      EXPECT_GT(resource_load_info->request_id, 0);
    EXPECT_EQ(mime_type, resource_load_info->mime_type);
    ASSERT_TRUE(resource_load_info->network_info->remote_endpoint);
    EXPECT_EQ(ip_address, resource_load_info->network_info->remote_endpoint
                              ->ToStringWithoutPort());
    EXPECT_EQ(was_cached, resource_load_info->was_cached);
    // Simple sanity check of the load timing info.
    auto CheckTime = [before_request, after_request](auto actual) {
      EXPECT_LE(before_request, actual);
      EXPECT_GT(after_request, actual);
    };
    const net::LoadTimingInfo& timing = resource_load_info->load_timing_info;
    CheckTime(timing.request_start);
    CheckTime(timing.receive_headers_end);
    CheckTime(timing.send_start);
    CheckTime(timing.send_end);
    if (!was_cached) {
      CheckTime(timing.connect_timing.dns_start);
      CheckTime(timing.connect_timing.dns_end);
      CheckTime(timing.connect_timing.connect_start);
      CheckTime(timing.connect_timing.connect_end);
    }
    if (file_size != -1) {
      EXPECT_EQ(file_size, resource_load_info->raw_body_bytes);
      EXPECT_LT(file_size, resource_load_info->total_received_bytes);
    }
  }
  EXPECT_TRUE(resource_load_info_found);
}

// Returns the resource with the given url if found, otherwise nullptr.
blink::mojom::ResourceLoadInfoPtr* ResourceLoadObserver::FindResource(
    const GURL& original_url) {
  for (auto& resource : resource_load_infos_) {
    if (resource->original_url == original_url)
      return &resource;
  }
  return nullptr;
}

void ResourceLoadObserver::Reset() {
  resource_load_infos_.clear();
  memory_cached_loaded_urls_.clear();
  resource_is_associated_with_main_frame_.clear();
}

void ResourceLoadObserver::WaitForResourceCompletion(const GURL& original_url) {
  // If we've already seen the resource, return immediately.
  for (const auto& load_info : resource_load_infos_) {
    if (load_info->original_url == original_url)
      return;
  }

  // Otherwise wait for it.
  base::RunLoop loop;
  waiting_original_url_ = original_url;
  waiting_callback_ = loop.QuitClosure();
  loop.Run();
}

// WebContentsObserver implementation:
void ResourceLoadObserver::ResourceLoadComplete(
    content::RenderFrameHost* render_frame_host,
    const GlobalRequestID& request_id,
    const blink::mojom::ResourceLoadInfo& resource_load_info) {
  EXPECT_NE(nullptr, render_frame_host);
  resource_load_infos_.push_back(resource_load_info.Clone());
  resource_is_associated_with_main_frame_.push_back(
      render_frame_host->GetParent() == nullptr);

  // Have we been waiting for this resource? If so, run the callback.
  if (waiting_original_url_.is_valid() &&
      resource_load_info.original_url == waiting_original_url_) {
    waiting_original_url_ = GURL();
    std::move(waiting_callback_).Run();
  }
}

void ResourceLoadObserver::DidLoadResourceFromMemoryCache(
    const GURL& url,
    const std::string& mime_type,
    network::mojom::RequestDestination request_destination) {
  memory_cached_loaded_urls_.push_back(url);
}

}  // namespace content
