// Copyright 2014 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 "mojo/services/network/network_context.h"

#include <algorithm>
#include <vector>

#include "base/base_paths.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "mojo/services/network/url_loader_impl.h"
#include "net/log/net_log_util.h"
#include "net/log/write_to_file_net_log_observer.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"

namespace mojo {

namespace {

// Logs network information to the specified file.
const char kLogNetLog[] = "log-net-log";

base::FilePath GetCacheDirectory(const base::FilePath& base_path) {
  return base_path.Append(FILE_PATH_LITERAL("Cache"));
}

std::string GetUserAgent() {
  // TODO(vtl): Haha, very funny.
  return "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like "
         "Gecko) Chrome/42.0.2311.68 Safari/537.36";
}

}  // namespace

class NetworkContext::MojoNetLog : public net::NetLog {
 public:
  MojoNetLog() {
    const base::CommandLine* command_line =
        base::CommandLine::ForCurrentProcess();
    if (!command_line->HasSwitch(kLogNetLog))
      return;

    base::FilePath log_path = command_line->GetSwitchValuePath(kLogNetLog);
    base::ScopedFILE file;
#if defined(OS_WIN)
    file.reset(_wfopen(log_path.value().c_str(), L"w"));
#elif defined(OS_POSIX)
    file.reset(fopen(log_path.value().c_str(), "w"));
#endif
    if (!file) {
      LOG(ERROR) << "Could not open file " << log_path.value()
                 << " for net logging";
    } else {
      write_to_file_observer_.reset(new net::WriteToFileNetLogObserver());
      write_to_file_observer_->set_capture_mode(
          net::NetLogCaptureMode::IncludeCookiesAndCredentials());
      write_to_file_observer_->StartObserving(this, file.Pass(), nullptr,
                                              nullptr);
    }
  }

  ~MojoNetLog() override {
    if (write_to_file_observer_)
      write_to_file_observer_->StopObserving(nullptr);
  }

 private:
  scoped_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_;

  DISALLOW_COPY_AND_ASSIGN(MojoNetLog);
};

// static
void NetworkContext::ClearCache(const base::FilePath& base_path,
                                scoped_refptr<base::TaskRunner> task_runner,
                                const base::Closure& clear_finished_callback) {
  base::FilePath trash_dir = base_path.Append(FILE_PATH_LITERAL("Trash"));
  base::CreateDirectory(trash_dir);
  base::FilePath dest_dir;
  base::CreateTemporaryDirInDir(trash_dir, "", &dest_dir);

  // Move the current cache directory, if present, into trash.
  base::FilePath cache_dir = GetCacheDirectory(base_path);
  if (PathExists(cache_dir)) {
    base::File::Error error;
    if (!base::ReplaceFile(cache_dir, dest_dir, &error)) {
      LOG(ERROR) << "Failed to clear cache content: " << error;
    }
  }
  // Recreate the cache directory.
  base::CreateDirectory(cache_dir);

  task_runner->PostTaskAndReply(
      FROM_HERE,
      base::Bind(base::IgnoreResult(&base::DeleteFile), trash_dir, true),
      clear_finished_callback);
}

NetworkContext::NetworkContext(
    scoped_ptr<net::URLRequestContext> url_request_context)
    : net_log_(new MojoNetLog),
      url_request_context_(url_request_context.Pass()),
      in_shutdown_(false) {
  url_request_context_->set_net_log(net_log_.get());
}

NetworkContext::NetworkContext(const base::FilePath& base_path)
    : NetworkContext(MakeURLRequestContext(base_path)) {
}

NetworkContext::~NetworkContext() {
  in_shutdown_ = true;
  // TODO(darin): Be careful about destruction order of member variables?

  // Call each URLLoaderImpl and ask it to release its net::URLRequest, as the
  // corresponding net::URLRequestContext is going away with this
  // NetworkContext. The loaders can be deregistering themselves in Cleanup(),
  // so iterate over a copy.
  for (auto& url_loader : url_loaders_) {
    url_loader->Cleanup();
  }
}

void NetworkContext::RegisterURLLoader(URLLoaderImpl* url_loader) {
  DCHECK(url_loaders_.count(url_loader) == 0);
  url_loaders_.insert(url_loader);
}

void NetworkContext::DeregisterURLLoader(URLLoaderImpl* url_loader) {
  if (!in_shutdown_) {
    size_t removed_count = url_loaders_.erase(url_loader);
    DCHECK(removed_count);
  }
}

size_t NetworkContext::GetURLLoaderCountForTesting() {
  return url_loaders_.size();
}

// static
scoped_ptr<net::URLRequestContext> NetworkContext::MakeURLRequestContext(
    const base::FilePath& base_path) {
  net::URLRequestContextBuilder builder;
  builder.set_accept_language("en-us,en");
  builder.set_user_agent(GetUserAgent());
  builder.set_proxy_service(net::ProxyService::CreateDirect());
  builder.set_transport_security_persister_path(base_path);
  builder.set_data_enabled(true);

  net::URLRequestContextBuilder::HttpCacheParams cache_params;
#if defined(OS_ANDROID)
  // On Android, we store the cache on disk becase we can run only a single
  // instance of the shell at a time.
  cache_params.type = net::URLRequestContextBuilder::HttpCacheParams::DISK;
  cache_params.path = GetCacheDirectory(base_path);
#else
  // On desktop, we store the cache in memory so we can run many shells
  // in parallel when running tests, otherwise the network services in each
  // shell will corrupt the disk cache.
  cache_params.type = net::URLRequestContextBuilder::HttpCacheParams::IN_MEMORY;
#endif

  builder.EnableHttpCache(cache_params);
  builder.set_file_enabled(true);

  return make_scoped_ptr(builder.Build());
}

}  // namespace mojo
