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

#include "services/network/transitional_url_loader_factory_owner.h"

#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/no_destructor.h"
#include "base/synchronization/atomic_flag.h"
#include "net/url_request/url_request_context_getter.h"
#include "services/network/network_context.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"

namespace network {

// Portion of TransitionalURLLoaderFactoryOwner that lives on the network
// task runner associated with the URLRequestContextGetter.
class TransitionalURLLoaderFactoryOwner::Core {
 public:
  Core(scoped_refptr<net::URLRequestContextGetter> url_request_context_getter)
      : url_request_context_getter_(std::move(url_request_context_getter)),
        task_runner_(url_request_context_getter_->GetNetworkTaskRunner()) {}

  void CreateNetworkContext(mojom::NetworkContextRequest request) {
    if (task_runner_->RunsTasksInCurrentSequence()) {
      // This must be synchronous since in same-runner case deletes are
      // synchronous as well.
      CreateNetworkContextOnNetworkThread(std::move(request));
    } else {
      // Unretained is safe since cross-thread deletes will also be posted.
      task_runner_->PostTask(
          FROM_HERE,
          base::BindOnce(&Core::CreateNetworkContextOnNetworkThread,
                         base::Unretained(this), std::move(request)));
    }
  }

  static void DeleteOnRightThread(std::unique_ptr<Core> instance) {
    scoped_refptr<base::SequencedTaskRunner> task_runner =
        instance->task_runner_;
    if (!task_runner->RunsTasksInCurrentSequence())
      task_runner->DeleteSoon(FROM_HERE, std::move(instance));
    // otherwise |instance| going out of scope will do the right thing.
  }

 private:
  friend class base::DeleteHelper<Core>;
  friend struct std::default_delete<Core>;

  ~Core() {
    DCHECK(url_request_context_getter_->GetURLRequestContext());
    DCHECK(task_runner_->RunsTasksInCurrentSequence());
  }

  void CreateNetworkContextOnNetworkThread(
      mojom::NetworkContextRequest request) {
    network_context_ = std::make_unique<network::NetworkContext>(
        nullptr /* network_service */, std::move(request),
        url_request_context_getter_->GetURLRequestContext());
  }

  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
  scoped_refptr<base::SequencedTaskRunner> task_runner_;
  std::unique_ptr<network::NetworkContext> network_context_;
};

TransitionalURLLoaderFactoryOwner::TransitionalURLLoaderFactoryOwner(
    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter)
    : core_(std::make_unique<Core>(std::move(url_request_context_getter))) {
  DCHECK(!disallowed_in_process().IsSet());
}

TransitionalURLLoaderFactoryOwner::~TransitionalURLLoaderFactoryOwner() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!disallowed_in_process().IsSet());

  if (shared_url_loader_factory_)
    shared_url_loader_factory_->Detach();

  Core::DeleteOnRightThread(std::move(core_));
}

scoped_refptr<network::SharedURLLoaderFactory>
TransitionalURLLoaderFactoryOwner::GetURLLoaderFactory() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!disallowed_in_process().IsSet());

  if (!shared_url_loader_factory_) {
    core_->CreateNetworkContext(mojo::MakeRequest(&network_context_pipe_));
    auto url_loader_factory_params =
        network::mojom::URLLoaderFactoryParams::New();
    url_loader_factory_params->process_id = mojom::kBrowserProcessId;
    url_loader_factory_params->is_corb_enabled = false;
    network_context_pipe_->CreateURLLoaderFactory(
        mojo::MakeRequest(&url_loader_factory_),
        std::move(url_loader_factory_params));
    shared_url_loader_factory_ =
        base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
            url_loader_factory_.get());
  }

  return shared_url_loader_factory_;
}

void TransitionalURLLoaderFactoryOwner::DisallowUsageInProcess() {
  disallowed_in_process().Set();
}

base::AtomicFlag& TransitionalURLLoaderFactoryOwner::disallowed_in_process() {
  static base::NoDestructor<base::AtomicFlag> instance;
  return *instance;
}

}  // namespace network
