// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/devtools/protocol/visual_debugger_handler.h"

#include <string.h>

#include <algorithm>

#include "base/functional/bind.h"
#include "base/json/json_writer.h"
#include "base/task/bind_post_task.h"
#include "base/task/single_thread_task_runner.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/inspector_protocol/crdtp/json.h"

namespace content {
namespace protocol {

VisualDebuggerHandler::VisualDebuggerHandler()
    : DevToolsDomainHandler(VisualDebugger::Metainfo::domainName) {}

VisualDebuggerHandler::~VisualDebuggerHandler() {
  StopStream();
}

void VisualDebuggerHandler::Wire(UberDispatcher* dispatcher) {
  frontend_ = std::make_unique<VisualDebugger::Frontend>(dispatcher->channel());
  VisualDebugger::Dispatcher::wire(dispatcher, this);
}

DispatchResponse VisualDebuggerHandler::FilterStream(
    std::unique_ptr<base::DictValue> in_filter) {
  auto* host = GetGpuProcessHost(/*force_create=*/true);
  if (!host) {
    return DispatchResponse::ServerError("GPU process is not available");
  }
  host->gpu_host()->FilterVisualDebugStream(std::move(*in_filter));

  return DispatchResponse::Success();
}

DispatchResponse VisualDebuggerHandler::StartStream() {
  auto* host = GetGpuProcessHost(/*force_create=*/true);
  if (!host) {
    enabled_ = false;
    return DispatchResponse::ServerError("GPU process is not available");
  }
  enabled_ = true;
  host->gpu_host()->StartVisualDebugStream(base::BindPostTask(
      base::SingleThreadTaskRunner::GetCurrentDefault(),
      base::BindRepeating(&VisualDebuggerHandler::OnFrameResponse,
                          weak_ptr_factory_.GetWeakPtr()),
      FROM_HERE));
  return DispatchResponse::Success();
}

void VisualDebuggerHandler::OnFrameResponse(base::Value json) {
  // This should be called via the 'BindPostTask' in 'StartStream' function
  // above and thus should be in the correct thread.
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI),
        base::NotFatalUntil::M159);
  frontend_->FrameResponse(
      std::make_unique<base::DictValue>(std::move(json).TakeDict()));
}

DispatchResponse VisualDebuggerHandler::StopStream() {
  if (enabled_) {
    // Cleanup must not launch a replacement GPU process.
    auto* host = GetGpuProcessHost(/*force_create=*/false);
    if (host) {
      host->gpu_host()->StopVisualDebugStream();
    }
  }
  enabled_ = false;
  return DispatchResponse::Success();
}

GpuProcessHost* VisualDebuggerHandler::GetGpuProcessHost(bool force_create) {
  if (gpu_process_host_getter_for_testing_) {
    return gpu_process_host_getter_for_testing_.Run(force_create);
  }
  return GpuProcessHost::Get(GPU_PROCESS_KIND_SANDBOXED, force_create);
}

}  // namespace protocol
}  // namespace content
