// Copyright (c) 2013 The Chromium Embedded Framework 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 "libcef/browser/trace_subscriber.h"
#include "include/cef_trace.h"
#include "libcef/browser/thread_util.h"

#include "base/files/file_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "content/public/browser/tracing_controller.h"

namespace {

// Create the temporary file and then execute |callback| on the thread
// represented by |message_loop_proxy|.
void CreateTemporaryFileOnBackgroundThread(
    scoped_refptr<base::SequencedTaskRunner> message_loop_proxy,
    base::Callback<void(const base::FilePath&)> callback) {
  CEF_REQUIRE_BLOCKING();
  base::FilePath file_path;
  if (!base::CreateTemporaryFile(&file_path))
    LOG(ERROR) << "Failed to create temporary file.";
  message_loop_proxy->PostTask(FROM_HERE, base::Bind(callback, file_path));
}

// Release the wrapped callback object after completion.
class CefCompletionCallbackWrapper : public CefCompletionCallback {
 public:
  explicit CefCompletionCallbackWrapper(
      CefRefPtr<CefCompletionCallback> callback)
      : callback_(callback) {}

  void OnComplete() override {
    if (callback_) {
      callback_->OnComplete();
      callback_ = nullptr;
    }
  }

 private:
  CefRefPtr<CefCompletionCallback> callback_;

  IMPLEMENT_REFCOUNTING(CefCompletionCallbackWrapper);
  DISALLOW_COPY_AND_ASSIGN(CefCompletionCallbackWrapper);
};

}  // namespace

using content::TracingController;

CefTraceSubscriber::CefTraceSubscriber()
    : collecting_trace_data_(false), weak_factory_(this) {
  CEF_REQUIRE_UIT();
}

CefTraceSubscriber::~CefTraceSubscriber() {
  CEF_REQUIRE_UIT();
  if (collecting_trace_data_)
    TracingController::GetInstance()->StopTracing(nullptr);
}

bool CefTraceSubscriber::BeginTracing(
    const std::string& categories,
    CefRefPtr<CefCompletionCallback> callback) {
  CEF_REQUIRE_UIT();

  if (collecting_trace_data_)
    return false;

  collecting_trace_data_ = true;

  TracingController::StartTracingDoneCallback done_callback;
  if (callback.get()) {
    // Work around a bug introduced in http://crbug.com/542390#c22 that keeps a
    // reference to |done_callback| after execution.
    callback = new CefCompletionCallbackWrapper(callback);
    done_callback =
        base::BindOnce(&CefCompletionCallback::OnComplete, callback.get());
  }

  TracingController::GetInstance()->StartTracing(
      base::trace_event::TraceConfig(categories, ""), std::move(done_callback));
  return true;
}

bool CefTraceSubscriber::EndTracing(const base::FilePath& tracing_file,
                                    CefRefPtr<CefEndTracingCallback> callback) {
  CEF_REQUIRE_UIT();

  if (!collecting_trace_data_)
    return false;

  if (!callback.get()) {
    // Discard the trace data.
    collecting_trace_data_ = false;
    TracingController::GetInstance()->StopTracing(nullptr);
    return true;
  }

  if (tracing_file.empty()) {
    // Create a new temporary file path on the FILE thread, then continue.
    CEF_POST_USER_VISIBLE_TASK(
        base::Bind(CreateTemporaryFileOnBackgroundThread,
                   base::ThreadTaskRunnerHandle::Get(),
                   base::Bind(&CefTraceSubscriber::ContinueEndTracing,
                              weak_factory_.GetWeakPtr(), callback)));
    return true;
  }

  base::Closure result_callback =
      base::Bind(&CefTraceSubscriber::OnTracingFileResult,
                 weak_factory_.GetWeakPtr(), callback, tracing_file);

  TracingController::GetInstance()->StopTracing(
      TracingController::CreateFileEndpoint(tracing_file, result_callback));
  return true;
}

void CefTraceSubscriber::ContinueEndTracing(
    CefRefPtr<CefEndTracingCallback> callback,
    const base::FilePath& tracing_file) {
  CEF_REQUIRE_UIT();
  if (!tracing_file.empty())
    EndTracing(tracing_file, callback);
}

void CefTraceSubscriber::OnTracingFileResult(
    CefRefPtr<CefEndTracingCallback> callback,
    const base::FilePath& tracing_file) {
  CEF_REQUIRE_UIT();

  collecting_trace_data_ = false;

  callback->OnEndTracingComplete(tracing_file.value());
}
