// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/network/url_request_context.h"

#include <string>

#include "base/threading/worker_pool.h"
#include "cobalt/network/network_delegate.h"
#include "cobalt/network/persistent_cookie_store.h"
#include "cobalt/network/proxy_config_service.h"
#include "net/base/cert_verify_proc.h"
#include "net/base/default_server_bound_cert_store.h"
#include "net/base/host_cache.h"
#include "net/base/multi_threaded_cert_verifier.h"
#include "net/base/server_bound_cert_service.h"
#include "net/base/ssl_config_service.h"
#include "net/base/ssl_config_service_defaults.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_cache.h"
#include "net/http/http_server_properties_impl.h"
#include "net/proxy/proxy_config.h"
#include "net/proxy/proxy_config_source.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_job_factory_impl.h"

namespace cobalt {
namespace network {
namespace {
net::ProxyConfig CreateCustomProxyConfig(const std::string& proxy_rules) {
  net::ProxyConfig proxy_config = net::ProxyConfig::CreateDirect();
  proxy_config.set_source(net::PROXY_CONFIG_SOURCE_CUSTOM);
  proxy_config.proxy_rules().ParseFromString(proxy_rules);
  return proxy_config;
}
}  // namespace

URLRequestContext::URLRequestContext(storage::StorageManager* storage_manager,
                                     const std::string& custom_proxy,
                                     net::NetLog* net_log,
                                     bool ignore_certificate_errors)
    : ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) {
  if (storage_manager) {
    persistent_cookie_store_ = new PersistentCookieStore(storage_manager);
  }
  storage_.set_cookie_store(
      new net::CookieMonster(persistent_cookie_store_, NULL /* delegate */));
  storage_.set_server_bound_cert_service(new net::ServerBoundCertService(
      new net::DefaultServerBoundCertStore(NULL),
      base::WorkerPool::GetTaskRunner(true)));

  base::optional<net::ProxyConfig> proxy_config;
  if (!custom_proxy.empty()) {
    proxy_config = CreateCustomProxyConfig(custom_proxy);
  }

  scoped_ptr<net::ProxyConfigService> proxy_config_service(
      new ProxyConfigService(proxy_config));
  storage_.set_proxy_service(net::ProxyService::CreateWithoutProxyResolver(
      proxy_config_service.release(), NULL));

  net::HostResolver::Options options;
  options.max_concurrent_resolves = net::HostResolver::kDefaultParallelism;
  options.max_retry_attempts = net::HostResolver::kDefaultRetryAttempts;
  options.enable_caching = true;
  storage_.set_host_resolver(
      net::HostResolver::CreateSystemResolver(options, NULL));

  storage_.set_cert_verifier(
      new net::MultiThreadedCertVerifier(net::CertVerifyProc::CreateDefault()));
  storage_.set_ssl_config_service(new net::SSLConfigServiceDefaults);

  storage_.set_http_auth_handler_factory(
      net::HttpAuthHandlerFactory::CreateDefault(host_resolver()));
  storage_.set_http_server_properties(new net::HttpServerPropertiesImpl);

  net::HttpNetworkSession::Params params;
  params.client_socket_factory = NULL;
  params.host_resolver = host_resolver();
  params.cert_verifier = cert_verifier();
  params.server_bound_cert_service = server_bound_cert_service();
  params.transport_security_state = NULL;
  params.proxy_service = proxy_service();
  params.ssl_session_cache_shard = "";
  params.ssl_config_service = ssl_config_service();
  params.http_auth_handler_factory = http_auth_handler_factory();
  params.network_delegate = NULL;
  params.http_server_properties = http_server_properties();
#if defined(ENABLE_NETWORK_LOGGING)
  params.net_log = net_log;
  set_net_log(net_log);
#else
  UNREFERENCED_PARAMETER(net_log);
#endif
  params.trusted_spdy_proxy = "";
#if defined(ENABLE_IGNORE_CERTIFICATE_ERRORS)
  params.ignore_certificate_errors = ignore_certificate_errors;
#else
  UNREFERENCED_PARAMETER(ignore_certificate_errors);
#endif  // defined(ENABLE_IGNORE_CERTIFICATE_ERRORS)

  // disable caching
  net::HttpCache* cache = new net::HttpCache(params, NULL /* backend */);
  cache->set_mode(net::HttpCache::DISABLE);
  storage_.set_http_transaction_factory(cache);

  storage_.set_job_factory(new net::URLRequestJobFactoryImpl());
}

URLRequestContext::~URLRequestContext() {}

void URLRequestContext::SetProxy(const std::string& proxy_rules) {
  net::ProxyConfig proxy_config = CreateCustomProxyConfig(proxy_rules);
  // ProxyService takes ownership of the ProxyConfigService.
  proxy_service()->ResetConfigService(new ProxyConfigService(proxy_config));
}

}  // namespace network
}  // namespace cobalt
