// This file is generated by TypeBuilder_cpp.template.

// 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 "chrome/browser/devtools/protocol/browser.h"

#include "chrome/browser/devtools/protocol/protocol.h"

#include "third_party/inspector_protocol/crdtp/cbor.h"
#include "third_party/inspector_protocol/crdtp/find_by_first.h"
#include "third_party/inspector_protocol/crdtp/span.h"

namespace protocol {
namespace Browser {

using crdtp::DeserializerState;
using crdtp::FallthroughCallback;
using crdtp::ProtocolTypeTraits;

// ------------- Enum values from types.

const char Metainfo::domainName[] = "Browser";
const char Metainfo::commandPrefix[] = "Browser.";
const char Metainfo::version[] = "1.3";




CRDTP_BEGIN_DESERIALIZER(Bounds)
    CRDTP_DESERIALIZE_FIELD_OPT("height", m_height),
    CRDTP_DESERIALIZE_FIELD_OPT("left", m_left),
    CRDTP_DESERIALIZE_FIELD_OPT("top", m_top),
    CRDTP_DESERIALIZE_FIELD_OPT("width", m_width),
    CRDTP_DESERIALIZE_FIELD_OPT("windowState", m_windowState),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(Bounds)
    CRDTP_SERIALIZE_FIELD("left", m_left);
    CRDTP_SERIALIZE_FIELD("top", m_top);
    CRDTP_SERIALIZE_FIELD("width", m_width);
    CRDTP_SERIALIZE_FIELD("height", m_height);
    CRDTP_SERIALIZE_FIELD("windowState", m_windowState);
CRDTP_END_SERIALIZER();



// ------------- Enum values from params.


// ------------- Frontend notifications.

void Frontend::flush()
{
    frontend_channel_->FlushProtocolNotifications();
}

void Frontend::sendRawNotification(std::unique_ptr<Serializable> notification)
{
    frontend_channel_->SendProtocolNotification(std::move(notification));
}

// --------------------- Dispatcher.

class DomainDispatcherImpl : public protocol::DomainDispatcher {
public:
    DomainDispatcherImpl(FrontendChannel* frontendChannel, Backend* backend)
        : DomainDispatcher(frontendChannel)
        , m_backend(backend) {}
    ~DomainDispatcherImpl() override { }

    using CallHandler = void (DomainDispatcherImpl::*)(crdtp::Dispatchable& dispatchable);

    bool Dispatch(crdtp::span<uint8_t> command_name, crdtp::Dispatchable& dispatchable) override;

    void close(crdtp::Dispatchable& dispatchable);
    void getWindowBounds(crdtp::Dispatchable& dispatchable);
    void getWindowForTarget(crdtp::Dispatchable& dispatchable);
    void setWindowBounds(crdtp::Dispatchable& dispatchable);
    void setContentsSize(crdtp::Dispatchable& dispatchable);
    void setDockTile(crdtp::Dispatchable& dispatchable);
    void executeBrowserCommand(crdtp::Dispatchable& dispatchable);
    void addPrivacySandboxEnrollmentOverride(crdtp::Dispatchable& dispatchable);
 protected:
    Backend* m_backend;
};

namespace {
// This helper method with a static map of command methods (instance methods
// of DomainDispatcherImpl declared just above) by their name is used immediately below,
// in the DomainDispatcherImpl::Dispatch method.
DomainDispatcherImpl::CallHandler CommandByName(crdtp::span<uint8_t> command_name) {
  static auto* commands = [](){
    auto* commands = new std::vector<std::pair<crdtp::span<uint8_t>,
                              DomainDispatcherImpl::CallHandler>>{
    {
          crdtp::SpanFrom("addPrivacySandboxEnrollmentOverride"),
          &DomainDispatcherImpl::addPrivacySandboxEnrollmentOverride
    },
    {
          crdtp::SpanFrom("close"),
          &DomainDispatcherImpl::close
    },
    {
          crdtp::SpanFrom("executeBrowserCommand"),
          &DomainDispatcherImpl::executeBrowserCommand
    },
    {
          crdtp::SpanFrom("getWindowBounds"),
          &DomainDispatcherImpl::getWindowBounds
    },
    {
          crdtp::SpanFrom("getWindowForTarget"),
          &DomainDispatcherImpl::getWindowForTarget
    },
    {
          crdtp::SpanFrom("setContentsSize"),
          &DomainDispatcherImpl::setContentsSize
    },
    {
          crdtp::SpanFrom("setDockTile"),
          &DomainDispatcherImpl::setDockTile
    },
    {
          crdtp::SpanFrom("setWindowBounds"),
          &DomainDispatcherImpl::setWindowBounds
    },
    };
    return commands;
  }();
  return crdtp::FindByFirst<DomainDispatcherImpl::CallHandler>(*commands, command_name, nullptr);
}
}  // namespace

bool DomainDispatcherImpl::Dispatch(crdtp::span<uint8_t> command_name, crdtp::Dispatchable& dispatchable) {
  CallHandler handler = CommandByName(command_name);
  if (!handler) return false;

  (this->*handler)(dispatchable);
  return true;
}


namespace {


}  // namespace

void DomainDispatcherImpl::close(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->Close();
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct getWindowBoundsParams : public crdtp::DeserializableProtocolObject<getWindowBoundsParams> {
    int windowId;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(getWindowBoundsParams)
    CRDTP_DESERIALIZE_FIELD("windowId", windowId),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::getWindowBounds(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    getWindowBoundsParams params;
    if (!getWindowBoundsParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }
    // Declare output parameters.
    std::unique_ptr<protocol::Browser::Bounds> out_bounds;

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->GetWindowBounds(params.windowId, &out_bounds);
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
      if (weak->get()) {
        std::unique_ptr<crdtp::Serializable> result;
        if (response.IsSuccess()) {
          crdtp::ObjectSerializer serializer;
          serializer.AddField(crdtp::MakeSpan("bounds"), out_bounds);
          result = serializer.Finish();
        } else {
          result = Serializable::From({});
        }
        weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result));
      }
    return;
}

namespace {

struct getWindowForTargetParams : public crdtp::DeserializableProtocolObject<getWindowForTargetParams> {
    std::optional<String> targetId;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(getWindowForTargetParams)
    CRDTP_DESERIALIZE_FIELD_OPT("targetId", targetId),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::getWindowForTarget(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    getWindowForTargetParams params;
    if (!getWindowForTargetParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }
    // Declare output parameters.
    int out_windowId;
    std::unique_ptr<protocol::Browser::Bounds> out_bounds;

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->GetWindowForTarget(std::move(params.targetId), &out_windowId, &out_bounds);
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
      if (weak->get()) {
        std::unique_ptr<crdtp::Serializable> result;
        if (response.IsSuccess()) {
          crdtp::ObjectSerializer serializer;
          serializer.AddField(crdtp::MakeSpan("windowId"), out_windowId);
          serializer.AddField(crdtp::MakeSpan("bounds"), out_bounds);
          result = serializer.Finish();
        } else {
          result = Serializable::From({});
        }
        weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result));
      }
    return;
}

namespace {

struct setWindowBoundsParams : public crdtp::DeserializableProtocolObject<setWindowBoundsParams> {
    int windowId;
    std::unique_ptr<protocol::Browser::Bounds> bounds;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setWindowBoundsParams)
    CRDTP_DESERIALIZE_FIELD("bounds", bounds),
    CRDTP_DESERIALIZE_FIELD("windowId", windowId),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setWindowBounds(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setWindowBoundsParams params;
    if (!setWindowBoundsParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetWindowBounds(params.windowId, std::move(params.bounds));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setContentsSizeParams : public crdtp::DeserializableProtocolObject<setContentsSizeParams> {
    int windowId;
    std::optional<int> width;
    std::optional<int> height;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setContentsSizeParams)
    CRDTP_DESERIALIZE_FIELD_OPT("height", height),
    CRDTP_DESERIALIZE_FIELD_OPT("width", width),
    CRDTP_DESERIALIZE_FIELD("windowId", windowId),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setContentsSize(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setContentsSizeParams params;
    if (!setContentsSizeParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetContentsSize(params.windowId, std::move(params.width), std::move(params.height));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setDockTileParams : public crdtp::DeserializableProtocolObject<setDockTileParams> {
    std::optional<String> badgeLabel;
    std::optional<Binary> image;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setDockTileParams)
    CRDTP_DESERIALIZE_FIELD_OPT("badgeLabel", badgeLabel),
    CRDTP_DESERIALIZE_FIELD_OPT("image", image),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setDockTile(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setDockTileParams params;
    if (!setDockTileParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetDockTile(std::move(params.badgeLabel), std::move(params.image));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct executeBrowserCommandParams : public crdtp::DeserializableProtocolObject<executeBrowserCommandParams> {
    String commandId;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(executeBrowserCommandParams)
    CRDTP_DESERIALIZE_FIELD("commandId", commandId),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::executeBrowserCommand(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    executeBrowserCommandParams params;
    if (!executeBrowserCommandParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->ExecuteBrowserCommand(params.commandId);
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct addPrivacySandboxEnrollmentOverrideParams : public crdtp::DeserializableProtocolObject<addPrivacySandboxEnrollmentOverrideParams> {
    String url;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(addPrivacySandboxEnrollmentOverrideParams)
    CRDTP_DESERIALIZE_FIELD("url", url),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::addPrivacySandboxEnrollmentOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    addPrivacySandboxEnrollmentOverrideParams params;
    if (!addPrivacySandboxEnrollmentOverrideParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->AddPrivacySandboxEnrollmentOverride(params.url);
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {
// This helper method (with a static map of redirects) is used from Dispatcher::wire
// immediately below.
const std::vector<std::pair<crdtp::span<uint8_t>, crdtp::span<uint8_t>>>& SortedRedirects() {
  static auto* redirects = [](){
    auto* redirects = new std::vector<std::pair<crdtp::span<uint8_t>, crdtp::span<uint8_t>>>{
    };
    return redirects;
  }();
  return *redirects;
}
}  // namespace

// static
void Dispatcher::wire(UberDispatcher* uber, Backend* backend)
{
    auto dispatcher = std::make_unique<DomainDispatcherImpl>(uber->channel(), backend);
    uber->WireBackend(crdtp::SpanFrom("Browser"), SortedRedirects(), std::move(dispatcher));
}

} // Browser
} // namespace protocol
