// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/proxy_resolution/mock_proxy_resolver.h"

#include <memory>
#include <utility>

#include "base/check.h"
#include "base/ranges/algorithm.h"

namespace net {

MockAsyncProxyResolver::RequestImpl::RequestImpl(std::unique_ptr<Job> job)
    : job_(std::move(job)) {
  DCHECK(job_);
}

MockAsyncProxyResolver::RequestImpl::~RequestImpl() {
  MockAsyncProxyResolver* resolver = job_->Resolver();
  // AddCancelledJob will check if request is already cancelled
  resolver->AddCancelledJob(std::move(job_));
}

LoadState MockAsyncProxyResolver::RequestImpl::GetLoadState() {
  return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
}

MockAsyncProxyResolver::Job::Job(MockAsyncProxyResolver* resolver,
                                 const GURL& url,
                                 ProxyInfo* results,
                                 CompletionOnceCallback callback)
    : resolver_(resolver),
      url_(url),
      results_(results),
      callback_(std::move(callback)) {}

MockAsyncProxyResolver::Job::~Job() = default;

void MockAsyncProxyResolver::Job::CompleteNow(int rv) {
  CompletionOnceCallback callback = std::move(callback_);

  resolver_->RemovePendingJob(this);

  std::move(callback).Run(rv);
}

MockAsyncProxyResolver::~MockAsyncProxyResolver() = default;

int MockAsyncProxyResolver::GetProxyForURL(
    const GURL& url,
    const NetworkAnonymizationKey& network_anonymization_key,
    ProxyInfo* results,
    CompletionOnceCallback callback,
    std::unique_ptr<Request>* request,
    const NetLogWithSource& /*net_log*/) {
  auto job = std::make_unique<Job>(this, url, results, std::move(callback));

  pending_jobs_.push_back(job.get());
  *request = std::make_unique<RequestImpl>(std::move(job));

  // Test code completes the request by calling job->CompleteNow().
  return ERR_IO_PENDING;
}

void MockAsyncProxyResolver::AddCancelledJob(std::unique_ptr<Job> job) {
  auto it = base::ranges::find(pending_jobs_, job.get());
  // Because this is called always when RequestImpl is destructed,
  // we need to check if it is still in pending jobs.
  if (it != pending_jobs_.end()) {
    cancelled_jobs_.push_back(std::move(job));
    pending_jobs_.erase(it);
  }
}

void MockAsyncProxyResolver::RemovePendingJob(Job* job) {
  DCHECK(job);
  auto it = base::ranges::find(pending_jobs_, job);
  DCHECK(it != pending_jobs_.end());
  pending_jobs_.erase(it);
}

MockAsyncProxyResolver::MockAsyncProxyResolver() = default;

MockAsyncProxyResolverFactory::Request::Request(
    MockAsyncProxyResolverFactory* factory,
    const scoped_refptr<PacFileData>& script_data,
    std::unique_ptr<ProxyResolver>* resolver,
    CompletionOnceCallback callback)
    : factory_(factory),
      script_data_(script_data),
      resolver_(resolver),
      callback_(std::move(callback)) {}

MockAsyncProxyResolverFactory::Request::~Request() = default;

void MockAsyncProxyResolverFactory::Request::CompleteNow(
    int rv,
    std::unique_ptr<ProxyResolver> resolver) {
  *resolver_ = std::move(resolver);

  // RemovePendingRequest may remove the last external reference to |this|.
  scoped_refptr<MockAsyncProxyResolverFactory::Request> keep_alive(this);
  factory_->RemovePendingRequest(this);
  factory_ = nullptr;
  std::move(callback_).Run(rv);
}

void MockAsyncProxyResolverFactory::Request::CompleteNowWithForwarder(
    int rv,
    ProxyResolver* resolver) {
  DCHECK(resolver);
  CompleteNow(rv, std::make_unique<ForwardingProxyResolver>(resolver));
}

void MockAsyncProxyResolverFactory::Request::FactoryDestroyed() {
  factory_ = nullptr;
}

class MockAsyncProxyResolverFactory::Job
    : public ProxyResolverFactory::Request {
 public:
  explicit Job(
      const scoped_refptr<MockAsyncProxyResolverFactory::Request>& request)
      : request_(request) {}
  ~Job() override {
    if (request_->factory_) {
      request_->factory_->cancelled_requests_.push_back(request_);
      request_->factory_->RemovePendingRequest(request_.get());
    }
  }

 private:
  scoped_refptr<MockAsyncProxyResolverFactory::Request> request_;
};

MockAsyncProxyResolverFactory::MockAsyncProxyResolverFactory(
    bool resolvers_expect_pac_bytes)
    : ProxyResolverFactory(resolvers_expect_pac_bytes) {
}

int MockAsyncProxyResolverFactory::CreateProxyResolver(
    const scoped_refptr<PacFileData>& pac_script,
    std::unique_ptr<ProxyResolver>* resolver,
    CompletionOnceCallback callback,
    std::unique_ptr<ProxyResolverFactory::Request>* request_handle) {
  auto request = base::MakeRefCounted<Request>(this, pac_script, resolver,
                                               std::move(callback));
  pending_requests_.push_back(request);

  *request_handle = std::make_unique<Job>(request);

  // Test code completes the request by calling request->CompleteNow().
  return ERR_IO_PENDING;
}

void MockAsyncProxyResolverFactory::RemovePendingRequest(Request* request) {
  auto it = base::ranges::find(pending_requests_, request);
  DCHECK(it != pending_requests_.end());
  pending_requests_.erase(it);
}

MockAsyncProxyResolverFactory::~MockAsyncProxyResolverFactory() {
  for (auto& request : pending_requests_) {
    request->FactoryDestroyed();
  }
}

ForwardingProxyResolver::ForwardingProxyResolver(ProxyResolver* impl)
    : impl_(impl) {
}

int ForwardingProxyResolver::GetProxyForURL(
    const GURL& query_url,
    const NetworkAnonymizationKey& network_anonymization_key,
    ProxyInfo* results,
    CompletionOnceCallback callback,
    std::unique_ptr<Request>* request,
    const NetLogWithSource& net_log) {
  return impl_->GetProxyForURL(query_url, network_anonymization_key, results,
                               std::move(callback), request, net_log);
}

}  // namespace net
