// Copyright 2018 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.

#ifndef COMPONENTS_UPDATE_CLIENT_NET_URL_LOADER_POST_INTERCEPTOR_H_
#define COMPONENTS_UPDATE_CLIENT_NET_URL_LOADER_POST_INTERCEPTOR_H_

#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "base/callback.h"
#include "base/containers/queue.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_status_code.h"
#include "url/gurl.h"

namespace network {
class TestURLLoaderFactory;
}

namespace net {
namespace test_server {
class EmbeddedTestServer;
class HttpResponse;
struct HttpRequest;
}  // namespace test_server
}  // namespace net

namespace update_client {

// Intercepts requests to a file path, counts them, and captures the body of
// the requests. Optionally, for each request, it can return a canned response
// from a given file. The class maintains a queue of expectations, and returns
// one and only one response for each request that matches the expectation.
// Then, the expectation is removed from the queue.
class URLLoaderPostInterceptor {
 public:
  using InterceptedRequest =
      std::tuple<std::string, net::HttpRequestHeaders, GURL>;

  // Called when the load associated with the url request is intercepted
  // by this object:.
  using UrlJobRequestReadyCallback = base::OnceCallback<void()>;

  // Allows a generic string maching interface when setting up expectations.
  class RequestMatcher {
   public:
    virtual bool Match(const std::string& actual) const = 0;
    virtual ~RequestMatcher() {}
  };

  explicit URLLoaderPostInterceptor(
      network::TestURLLoaderFactory* url_loader_factory);
  URLLoaderPostInterceptor(std::vector<GURL> supported_urls,
                           network::TestURLLoaderFactory* url_loader_factory);
  URLLoaderPostInterceptor(std::vector<GURL> supported_urls,
                           net::test_server::EmbeddedTestServer*);

  ~URLLoaderPostInterceptor();

  // Sets an expection for the body of the POST request and optionally,
  // provides a canned response identified by a |file_path| to be returned when
  // the expectation is met. If no |file_path| is provided, then an empty
  // response body is served. If |response_code| is provided, then an empty
  // response body with that response code is returned.
  // Returns |true| if the expectation was set.
  bool ExpectRequest(std::unique_ptr<RequestMatcher> request_matcher);

  bool ExpectRequest(std::unique_ptr<RequestMatcher> request_matcher,
                     net::HttpStatusCode response_code);

  bool ExpectRequest(std::unique_ptr<RequestMatcher> request_matcher,
                     const base::FilePath& filepath);

  // Returns how many requests have been intercepted and matched by
  // an expectation. One expectation can only be matched by one request.
  int GetHitCount() const;

  // Returns how many requests in total have been captured by the interceptor.
  int GetCount() const;

  // Returns all requests that have been intercepted, matched or not.
  std::vector<InterceptedRequest> GetRequests() const;

  // Return the body of the n-th request, zero-based.
  std::string GetRequestBody(size_t n) const;

  // Returns the joined bodies of all requests for debugging purposes.
  std::string GetRequestsAsString() const;

  // Resets the state of the interceptor so that new expectations can be set.
  void Reset();

  // Prevents the intercepted request from starting, as a way to simulate
  // the effects of a very slow network. Call this function before the actual
  // network request occurs.
  void Pause();

  // Allows a previously paused request to continue.
  void Resume();

  // Sets a callback to be invoked when the request job associated with
  // an intercepted request is created. This allows the test execution to
  // synchronize with network tasks running on the IO thread and avoid polling
  // using idle run loops. A paused request can be resumed after this callback
  // has been invoked.
  void url_job_request_ready_callback(
      UrlJobRequestReadyCallback url_job_request_ready_callback);

  int GetHitCountForURL(const GURL& url);

 private:
  void InitializeWithInterceptor();
  void InitializeWithRequestHandler();

  std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
      const net::test_server::HttpRequest& request);

  struct ExpectationResponse {
    ExpectationResponse(net::HttpStatusCode code, const std::string& body)
        : response_code(code), response_body(body) {}
    const net::HttpStatusCode response_code;
    const std::string response_body;
  };
  using Expectation =
      std::pair<std::unique_ptr<RequestMatcher>, ExpectationResponse>;

  using PendingExpectation = std::pair<GURL, ExpectationResponse>;

  // Contains the count of the request matching expectations.
  int hit_count_ = 0;

  // Contains the request body and the extra headers of the intercepted
  // requests.
  std::vector<InterceptedRequest> requests_;

  // Contains the expectations which this interceptor tries to match.
  base::queue<Expectation> expectations_;

  base::queue<PendingExpectation> pending_expectations_;

  network::TestURLLoaderFactory* url_loader_factory_ = nullptr;
  net::test_server::EmbeddedTestServer* embedded_test_server_ = nullptr;

  bool is_paused_ = false;

  std::vector<GURL> filtered_urls_;

  UrlJobRequestReadyCallback url_job_request_ready_callback_;

  DISALLOW_COPY_AND_ASSIGN(URLLoaderPostInterceptor);
};

class PartialMatch : public URLLoaderPostInterceptor::RequestMatcher {
 public:
  explicit PartialMatch(const std::string& expected) : expected_(expected) {}
  bool Match(const std::string& actual) const override;

 private:
  const std::string expected_;

  DISALLOW_COPY_AND_ASSIGN(PartialMatch);
};

class AnyMatch : public URLLoaderPostInterceptor::RequestMatcher {
 public:
  AnyMatch() = default;
  bool Match(const std::string& actual) const override;

 private:
  DISALLOW_COPY_AND_ASSIGN(AnyMatch);
};

}  // namespace update_client

#endif  // COMPONENTS_UPDATE_CLIENT_NET_URL_LOADER_POST_INTERCEPTOR_H_
