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

#include "components/ui_devtools/devtools_client.h"

#include <string_view>

#include "base/notimplemented.h"
#include "components/ui_devtools/devtools_server.h"
#include "third_party/inspector_protocol/crdtp/dispatch.h"
#include "third_party/inspector_protocol/crdtp/json.h"

namespace ui_devtools {

UiDevToolsClient::UiDevToolsClient(const std::string& name,
                                   UiDevToolsServer* server)
    : name_(name),
      connection_id_(kNotConnected),
      dispatcher_(this),
      server_(server) {
  DCHECK(server_);
}

UiDevToolsClient::~UiDevToolsClient() = default;

void UiDevToolsClient::AddAgent(std::unique_ptr<UiDevToolsAgent> agent) {
  agent->Init(&dispatcher_);
  agents_.push_back(std::move(agent));
}

void UiDevToolsClient::Disconnect() {
  connection_id_ = kNotConnected;
  DisableAllAgents();
}

void UiDevToolsClient::Dispatch(const std::string& json) {
  std::vector<uint8_t> cbor;
  crdtp::Status status =
      crdtp::json::ConvertJSONToCBOR(crdtp::SpanFrom(json), &cbor);
  if (!status.ok()) {
    dispatcher_.channel()->SendProtocolNotification(
        crdtp::CreateErrorNotification(
            crdtp::DispatchResponse::ParseError(status.ToASCIIString())));
    return;
  }
  crdtp::Dispatchable dispatchable(crdtp::SpanFrom(cbor));
  if (dispatchable.ok()) {
    dispatcher_.Dispatch(dispatchable).Run();
    return;
  }
  if (dispatchable.HasCallId()) {
    dispatcher_.channel()->SendProtocolResponse(
        dispatchable.CallId(),
        crdtp::CreateErrorResponse(dispatchable.CallId(),
                                   dispatchable.DispatchError()));
  } else {
    dispatcher_.channel()->SendProtocolNotification(
        crdtp::CreateErrorNotification(dispatchable.DispatchError()));
  }
}

bool UiDevToolsClient::connected() const {
  return connection_id_ != kNotConnected;
}

void UiDevToolsClient::set_connection_id(int connection_id) {
  connection_id_ = connection_id;
}

const std::string& UiDevToolsClient::name() const {
  return name_;
}

void UiDevToolsClient::DisableAllAgents() {
  for (std::unique_ptr<UiDevToolsAgent>& agent : agents_)
    agent->Disable();
}

void UiDevToolsClient::MaybeSendProtocolResponseOrNotification(
    std::unique_ptr<protocol::Serializable> message) {
  if (!connected())
    return;

  std::string json;
  crdtp::Status status = crdtp::json::ConvertCBORToJSON(
      crdtp::SpanFrom(message->Serialize()), &json);
  DCHECK(status.ok());  // CBOR was generated by Chrome, so we expect it's ok.
  server_->SendOverWebSocket(connection_id_, std::string_view(json));
}

void UiDevToolsClient::SendProtocolResponse(
    int callId,
    std::unique_ptr<protocol::Serializable> message) {
  MaybeSendProtocolResponseOrNotification(std::move(message));
}

void UiDevToolsClient::SendProtocolNotification(
    std::unique_ptr<protocol::Serializable> message) {
  MaybeSendProtocolResponseOrNotification(std::move(message));
}

void UiDevToolsClient::FlushProtocolNotifications() {
  NOTIMPLEMENTED();
}

void UiDevToolsClient::FallThrough(int call_id,
                                   crdtp::span<uint8_t> method,
                                   crdtp::span<uint8_t> message) {
  NOTIMPLEMENTED();
}

}  // namespace ui_devtools
