// 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/mojo_net_log.h"

#include "base/callback.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/task_scheduler/post_task.h"
#include "base/task_scheduler/task_traits.h"
#include "base/values.h"
#include "net/log/file_net_log_observer.h"
#include "net/log/net_log_util.h"
#include "net/url_request/url_request_context.h"
#include "services/network/network_context.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/network_switches.h"

namespace network {

MojoNetLog::MojoNetLog() {}

MojoNetLog::~MojoNetLog() {
  if (file_net_log_observer_)
    file_net_log_observer_->StopObserving(nullptr /*polled_data*/,
                                          base::OnceClosure());
}

void MojoNetLog::ProcessCommandLine(const base::CommandLine& command_line) {
  if (!command_line.HasSwitch(switches::kLogNetLog))
    return;

  base::FilePath log_path =
      command_line.GetSwitchValuePath(switches::kLogNetLog);

  // TODO(eroman): Should get capture mode from the command line.
  net::NetLogCaptureMode capture_mode =
      net::NetLogCaptureMode::IncludeCookiesAndCredentials();

  file_net_log_observer_ = net::FileNetLogObserver::CreateUnbounded(
      log_path, nullptr /* constants */);
  file_net_log_observer_->StartObserving(this, capture_mode);
}

NetLogExporter::NetLogExporter(NetworkContext* network_context)
    : network_context_(network_context), state_(STATE_IDLE) {}

NetLogExporter::~NetLogExporter() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  // In case scratch directory creation didn't finish by the time |this| is
  // destroyed, |destination_| is still owned here (rather than handed over to
  // FileNetLogObserver); ask the scheduler to close it someplace suitable.
  if (destination_.IsValid())
    CloseFileOffThread(std::move(destination_));

  // ~FileNetLogObserver will take care of unregistering from NetLog even
  // if StopObserving isn't invoked.
}

void NetLogExporter::Start(base::File destination,
                           base::Value extra_constants,
                           NetLogExporter::CaptureMode capture_mode,
                           uint64_t max_file_size,
                           StartCallback callback) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(destination.IsValid());

  if (state_ != STATE_IDLE) {
    CloseFileOffThread(std::move(destination));
    std::move(callback).Run(net::ERR_UNEXPECTED);
    return;
  }

  // Store the file explicitly since destroying it involves disk I/O, so must
  // be carefully controlled.
  destination_ = std::move(destination);

  net::NetLogCaptureMode net_capture_mode;
  switch (capture_mode) {
    case NetLogExporter::CaptureMode::DEFAULT:
      net_capture_mode = net::NetLogCaptureMode::Default();
      break;
    case NetLogExporter::CaptureMode::INCLUDE_COOKIES_AND_CREDENTIALS:
      net_capture_mode = net::NetLogCaptureMode::IncludeCookiesAndCredentials();
      break;
    case NetLogExporter::CaptureMode::INCLUDE_SOCKET_BYTES:
      net_capture_mode = net::NetLogCaptureMode::IncludeSocketBytes();
      break;
  }

  state_ = STATE_WAITING_DIR;
  static_assert(kUnlimitedFileSize == net::FileNetLogObserver::kNoLimit,
                "Inconsistent unbounded size constants");
  if (max_file_size != kUnlimitedFileSize) {
    base::PostTaskWithTraitsAndReplyWithResult(
        FROM_HERE,
        {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
        base::BindOnce(&NetLogExporter::CreateScratchDir,
                       scratch_dir_create_handler_for_tests_),

        // Note: this a static method which takes a weak pointer as an argument,
        // so it will run if |this| is deleted.
        base::BindOnce(&NetLogExporter::StartWithScratchDirOrCleanup,
                       AsWeakPtr(), std::move(extra_constants),
                       net_capture_mode, max_file_size, std::move(callback)));
  } else {
    StartWithScratchDir(std::move(extra_constants), net_capture_mode,
                        max_file_size, std::move(callback), base::FilePath());
  }
}

void NetLogExporter::Stop(base::Value polled_data_value,
                          StopCallback callback) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  base::DictionaryValue* polled_data = nullptr;
  bool ok = polled_data_value.GetAsDictionary(&polled_data);
  DCHECK(ok);  // mojo is supposed to enforce that.

  if (state_ != STATE_RUNNING) {
    std::move(callback).Run(net::ERR_UNEXPECTED);
    return;
  }

  std::unique_ptr<base::DictionaryValue> net_info = net::GetNetInfo(
      network_context_->url_request_context(), net::NET_INFO_ALL_SOURCES);
  if (polled_data)
    net_info->MergeDictionary(polled_data);

  file_net_observer_->StopObserving(
      std::move(net_info),
      base::BindOnce([](StopCallback sc) { std::move(sc).Run(net::OK); },
                     std::move(callback)));
  file_net_observer_ = nullptr;
  state_ = STATE_IDLE;
}

void NetLogExporter::SetCreateScratchDirHandlerForTesting(
    const base::RepeatingCallback<base::FilePath()>& handler) {
  scratch_dir_create_handler_for_tests_ = handler;
}

void NetLogExporter::CloseFileOffThread(base::File file) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  if (file.IsValid()) {
    base::PostTaskWithTraits(
        FROM_HERE,
        {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
        base::BindOnce([](base::File f) { f.Close(); }, std::move(file)));
  }
}

base::FilePath NetLogExporter::CreateScratchDir(
    base::RepeatingCallback<base::FilePath()>
        scratch_dir_create_handler_for_tests) {
  if (scratch_dir_create_handler_for_tests)
    return scratch_dir_create_handler_for_tests.Run();

  base::ScopedTempDir scratch_dir;
  if (scratch_dir.CreateUniqueTempDir())
    return scratch_dir.Take();
  else
    return base::FilePath();
}

void NetLogExporter::StartWithScratchDirOrCleanup(
    base::WeakPtr<NetLogExporter> object,
    base::Value extra_constants,
    net::NetLogCaptureMode capture_mode,
    uint64_t max_file_size,
    StartCallback callback,
    const base::FilePath& scratch_dir_path) {
  NetLogExporter* instance = object.get();
  if (instance) {
    instance->StartWithScratchDir(std::move(extra_constants), capture_mode,
                                  max_file_size, std::move(callback),
                                  scratch_dir_path);
  } else if (!scratch_dir_path.empty()) {
    // An NetLogExporter got destroyed while it was trying to create a scratch
    // dir.
    base::PostTaskWithTraits(
        FROM_HERE,
        {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
        base::BindOnce(
            [](const base::FilePath& dir) {
              // The delete is non-recursive (2nd argument false) since the
              // only time this is invoked the directory is expected to be
              // empty.
              base::DeleteFile(dir, false);
            },
            scratch_dir_path));
  }
}

void NetLogExporter::StartWithScratchDir(
    base::Value extra_constants_value,
    net::NetLogCaptureMode capture_mode,
    uint64_t max_file_size,
    StartCallback callback,
    const base::FilePath& scratch_dir_path) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  base::DictionaryValue* extra_constants = nullptr;
  bool ok = extra_constants_value.GetAsDictionary(&extra_constants);
  DCHECK(ok);  // mojo is supposed to enforce that before Start() is invoked.

  if (scratch_dir_path.empty() && max_file_size != kUnlimitedFileSize) {
    state_ = STATE_IDLE;
    CloseFileOffThread(std::move(destination_));
    std::move(callback).Run(net::ERR_INSUFFICIENT_RESOURCES);
    return;
  }

  state_ = STATE_RUNNING;

  std::unique_ptr<base::DictionaryValue> constants = net::GetNetConstants();

  if (extra_constants)
    constants->MergeDictionary(extra_constants);

  if (max_file_size != kUnlimitedFileSize) {
    file_net_observer_ = net::FileNetLogObserver::CreateBoundedPreExisting(
        scratch_dir_path, std::move(destination_), max_file_size,
        std::move(constants));
  } else {
    DCHECK(scratch_dir_path.empty());
    file_net_observer_ = net::FileNetLogObserver::CreateUnboundedPreExisting(
        std::move(destination_), std::move(constants));
  }

  // There might not be a NetworkService object e.g. on iOS; in that case
  // assume this present NetworkContext is all there is.
  if (network_context_->network_service()) {
    network_context_->network_service()->CreateNetLogEntriesForActiveObjects(
        file_net_observer_.get());
  } else {
    std::set<net::URLRequestContext*> contexts;
    contexts.insert(network_context_->url_request_context());
    net::CreateNetLogEntriesForActiveObjects(contexts,
                                             file_net_observer_.get());
  }

  file_net_observer_->StartObserving(
      network_context_->url_request_context()->net_log(), capture_mode);
  std::move(callback).Run(net::OK);
}

}  // namespace network
