// 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 "chrome/browser/media/webrtc/webrtc_event_log_uploader.h"

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/load_flags.h"
#include "net/base/mime_util.h"
#include "net/http/http_status_code.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"

namespace {
// TODO(crbug.com/817495): Eliminate the duplication with other uploaders.
const char kUploadContentType[] = "multipart/form-data";
const char kBoundary[] = "----**--yradnuoBgoLtrapitluMklaTelgooG--**----";

constexpr size_t kExpectedMimeOverheadBytes = 1000;  // Intentional overshot.

constexpr size_t kMaxResponseSizeBytes = 1024;

// TODO(crbug.com/817495): Eliminate the duplication with other uploaders.
#if defined(OS_WIN)
const char kProduct[] = "Chrome";
#elif defined(OS_MACOSX)
const char kProduct[] = "Chrome_Mac";
#elif defined(OS_LINUX)
const char kProduct[] = "Chrome_Linux";
#elif defined(OS_ANDROID)
const char kProduct[] = "Chrome_Android";
#elif defined(OS_CHROMEOS)
const char kProduct[] = "Chrome_ChromeOS";
#else
#error Platform not supported.
#endif

constexpr net::NetworkTrafficAnnotationTag
    kWebrtcEventLogUploaderTrafficAnnotation =
        net::DefineNetworkTrafficAnnotation("webrtc_event_log_uploader", R"(
      semantics {
        sender: "WebRTC Event Log uploader module"
        description:
          "Uploads a WebRTC event log to a server called Crash. These logs "
          "will not contain private information. They will be used to "
          "improve WebRTC (fix bugs, tune performance, etc.)."
        trigger:
          "A Google service (e.g. Hangouts/Meet) has requested a peer "
          "connection to be logged, and the resulting event log to be uploaded "
          "at a time deemed to cause the least interference to the user (i.e., "
          "when the user is not busy making other VoIP calls)."
        data:
          "WebRTC events such as the timing of audio playout (but not the "
          "content), timing and size of RTP packets sent/received, etc."
        destination: GOOGLE_OWNED_SERVICE
      }
      policy {
        cookies_allowed: NO
        setting: "Feature controlled only through Chrome policy; "
                 "no user-facing control surface."
        chrome_policy {
          WebRtcEventLogCollectionAllowed {
            WebRtcEventLogCollectionAllowed: false
          }
        }
      })");

void AddFileContents(const char* filename,
                     const std::string& file_contents,
                     const std::string& content_type,
                     std::string* post_data) {
  // net::AddMultipartValueForUpload does almost what we want to do here, except
  // that it does not add the "filename" attribute. We hack it to force it to.
  std::string mime_value_name =
      base::StringPrintf("%s\"; filename=\"%s\"", filename, filename);
  net::AddMultipartValueForUpload(mime_value_name, file_contents, kBoundary,
                                  content_type, post_data);
}

std::string MimeContentType() {
  const char kBoundaryKeywordAndMisc[] = "; boundary=";

  std::string content_type;
  content_type.reserve(sizeof(content_type) + sizeof(kBoundaryKeywordAndMisc) +
                       sizeof(kBoundary));

  content_type.append(kUploadContentType);
  content_type.append(kBoundaryKeywordAndMisc);
  content_type.append(kBoundary);

  return content_type;
}

void BindURLLoaderFactoryRequest(
    network::mojom::URLLoaderFactoryRequest url_loader_factory_request) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory =
      g_browser_process->shared_url_loader_factory();
  DCHECK(shared_url_loader_factory);
  shared_url_loader_factory->Clone(std::move(url_loader_factory_request));
}

#if DCHECK_IS_ON()
void OnURLLoadUploadProgress(uint64_t current, uint64_t total) {
  std::string unit;
  if (total <= 1000) {
    unit = "bytes";
  } else if (total <= 1000 * 1000) {
    unit = "KBs";
    current /= 1000;
    total /= 1000;
  } else {
    unit = "MBs";
    current /= 1000 * 1000;
    total /= 1000 * 1000;
  }
  VLOG(1) << "WebRTC event log upload progress: " << current << " / " << total
          << " " << unit << ".";
}
#endif

}  // namespace

const char WebRtcEventLogUploaderImpl::kUploadURL[] =
    "https://clients2.google.com/cr/report";

std::unique_ptr<WebRtcEventLogUploader>
WebRtcEventLogUploaderImpl::Factory::Create(const WebRtcLogFileInfo& log_file,
                                            UploadResultCallback callback) {
  return std::make_unique<WebRtcEventLogUploaderImpl>(
      log_file, std::move(callback), kMaxRemoteLogFileSizeBytes);
}

std::unique_ptr<WebRtcEventLogUploader>
WebRtcEventLogUploaderImpl::Factory::CreateWithCustomMaxSizeForTesting(
    const WebRtcLogFileInfo& log_file,
    UploadResultCallback callback,
    size_t max_log_file_size_bytes) {
  return std::make_unique<WebRtcEventLogUploaderImpl>(
      log_file, std::move(callback), max_log_file_size_bytes);
}

WebRtcEventLogUploaderImpl::WebRtcEventLogUploaderImpl(
    const WebRtcLogFileInfo& log_file,
    UploadResultCallback callback,
    size_t max_log_file_size_bytes)
    : log_file_(log_file),
      callback_(std::move(callback)),
      max_log_file_size_bytes_(max_log_file_size_bytes),
      io_task_runner_(base::SequencedTaskRunnerHandle::Get()) {
  std::string upload_data;

  if (!PrepareUploadData(&upload_data)) {
    ReportResult(false);
    return;
  }

  StartUpload(upload_data);
}

WebRtcEventLogUploaderImpl::~WebRtcEventLogUploaderImpl() {
  // WebRtcEventLogUploaderImpl objects' deletion scenarios:
  // 1. Upload started and finished - |url_loader_| should have been reset
  //    so that we would be able to DCHECK and demonstrate that the determinant
  //    is maintained.
  // 2. Upload started and cancelled - behave similarly to a finished upload.
  // 3. The upload was never started, due to an early failure (e.g. file not
  //    found). In that case, |url_loader_| will not have been set.
  // 4. Chrome shutdown.
  if (io_task_runner_->RunsTasksInCurrentSequence()) {  // Scenarios 1-3.
    DCHECK(!url_loader_);
  } else {  // # Scenario #4 - Chrome shutdown.
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
    bool will_delete =
        io_task_runner_->DeleteSoon(FROM_HERE, url_loader_.release());
    DCHECK(!will_delete)
        << "Task runners must have been stopped by this stage of shutdown.";
  }
}

const WebRtcLogFileInfo& WebRtcEventLogUploaderImpl::GetWebRtcLogFileInfo()
    const {
  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
  return log_file_;
}

bool WebRtcEventLogUploaderImpl::Cancel() {
  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());

  if (!url_loader_) {
    // The upload either already completed, or was never properly started (due
    // to a file read failure, etc.).
    return false;
  }

  // Note that in this case, it might still be that the last bytes hit the
  // wire right as we attempt to cancel the upload. OnURLFetchComplete, however,
  // would not be called.
  url_loader_.reset();
  DeleteLogFile();
  return true;
}

bool WebRtcEventLogUploaderImpl::PrepareUploadData(std::string* upload_data) {
  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());

  std::string log_file_contents;
  if (!base::ReadFileToStringWithMaxSize(log_file_.path, &log_file_contents,
                                         max_log_file_size_bytes_)) {
    LOG(WARNING) << "Couldn't read event log file, or max file size exceeded.";
    return false;
  }

  DCHECK(upload_data->empty());
  upload_data->reserve(log_file_contents.size() + kExpectedMimeOverheadBytes);

  const std::string filename_str = log_file_.path.BaseName().MaybeAsASCII();
  if (filename_str.empty()) {
    LOG(WARNING) << "Log filename is not according to acceptable format.";
    return false;
  }

  const char* filename = filename_str.c_str();

  net::AddMultipartValueForUpload("prod", kProduct, kBoundary, "", upload_data);
  net::AddMultipartValueForUpload("ver",
                                  version_info::GetVersionNumber() + "-webrtc",
                                  kBoundary, "", upload_data);
  net::AddMultipartValueForUpload("guid", "0", kBoundary, "", upload_data);
  net::AddMultipartValueForUpload("type", filename, kBoundary, "", upload_data);
  AddFileContents(filename, log_file_contents, "application/log", upload_data);
  net::AddMultipartFinalDelimiterForUpload(kBoundary, upload_data);

  return true;
}

void WebRtcEventLogUploaderImpl::StartUpload(const std::string& upload_data) {
  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());

  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url = GURL(kUploadURL);
  resource_request->method = "POST";
  resource_request->load_flags =
      net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES;

  // Create a new mojo pipe. It's safe to pass this around and use
  // immediately, even though it needs to finish initialization on the UI
  // thread.
  network::mojom::URLLoaderFactoryPtr url_loader_factory_ptr;
  content::BrowserThread::PostTask(
      content::BrowserThread::UI, FROM_HERE,
      base::BindOnce(BindURLLoaderFactoryRequest,
                     mojo::MakeRequest(&url_loader_factory_ptr)));

  url_loader_ = network::SimpleURLLoader::Create(
      std::move(resource_request), kWebrtcEventLogUploaderTrafficAnnotation);
  url_loader_->AttachStringForUpload(upload_data, MimeContentType());
#if DCHECK_IS_ON()
  url_loader_->SetOnUploadProgressCallback(
      base::BindRepeating(OnURLLoadUploadProgress));
#endif

  // See comment in destructor for an explanation about why using
  // base::Unretained(this) is safe here.
  url_loader_->DownloadToString(
      url_loader_factory_ptr.get(),
      base::BindOnce(&WebRtcEventLogUploaderImpl::OnURLLoadComplete,
                     base::Unretained(this)),
      kMaxResponseSizeBytes);
}

void WebRtcEventLogUploaderImpl::OnURLLoadComplete(
    std::unique_ptr<std::string> response_body) {
  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
  DCHECK(url_loader_);

  const bool upload_successful = (response_body != nullptr);
  if (upload_successful) {
    // TODO(crbug.com/775415): Update chrome://webrtc-logs.
    if (response_body->empty()) {
      LOG(WARNING) << "WebRTC event log completed, but report ID unknown.";
    } else {
      // TODO(crbug.com/775415): Remove this when chrome://webrtc-logs updated.
      VLOG(1) << "WebRTC event log successfully uploaded: " << *response_body;
    }
  } else {
    LOG(WARNING) << "WebRTC event log upload failed.";
  }

  url_loader_.reset();  // Explicitly maintain determinant.

  ReportResult(upload_successful);
}

void WebRtcEventLogUploaderImpl::ReportResult(bool result) {
  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());

  // * If the upload was successful, the file is no longer needed.
  // * If the upload failed, we don't want to retry, because we run the risk of
  //   uploading significant amounts of data once again, only for the upload to
  //   fail again after (as an example) wasting 50MBs of upload bandwidth.
  // * If the file was not found, this will simply have no effect (other than
  //   to LOG() an error).
  // TODO(crbug.com/775415): Provide refined retrial behavior.
  DeleteLogFile();

  io_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(std::move(callback_), log_file_.path, result));
}

void WebRtcEventLogUploaderImpl::DeleteLogFile() {
  DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
  const bool deletion_successful =
      base::DeleteFile(log_file_.path, /*recursive=*/false);
  if (!deletion_successful) {
    // This is a somewhat serious (though unlikely) error, because now we'll
    // try to upload this file again next time Chrome launches.
    LOG(ERROR) << "Could not delete pending WebRTC event log file.";
  }
}
