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

#include "content/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 content {
namespace protocol {
namespace FedCm {

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

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

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





CRDTP_BEGIN_DESERIALIZER(Account)
    CRDTP_DESERIALIZE_FIELD("accountId", m_accountId),
    CRDTP_DESERIALIZE_FIELD("email", m_email),
    CRDTP_DESERIALIZE_FIELD("givenName", m_givenName),
    CRDTP_DESERIALIZE_FIELD("idpConfigUrl", m_idpConfigUrl),
    CRDTP_DESERIALIZE_FIELD("idpLoginUrl", m_idpLoginUrl),
    CRDTP_DESERIALIZE_FIELD("loginState", m_loginState),
    CRDTP_DESERIALIZE_FIELD("name", m_name),
    CRDTP_DESERIALIZE_FIELD("pictureUrl", m_pictureUrl),
    CRDTP_DESERIALIZE_FIELD_OPT("privacyPolicyUrl", m_privacyPolicyUrl),
    CRDTP_DESERIALIZE_FIELD_OPT("termsOfServiceUrl", m_termsOfServiceUrl),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(Account)
    CRDTP_SERIALIZE_FIELD("accountId", m_accountId);
    CRDTP_SERIALIZE_FIELD("email", m_email);
    CRDTP_SERIALIZE_FIELD("name", m_name);
    CRDTP_SERIALIZE_FIELD("givenName", m_givenName);
    CRDTP_SERIALIZE_FIELD("pictureUrl", m_pictureUrl);
    CRDTP_SERIALIZE_FIELD("idpConfigUrl", m_idpConfigUrl);
    CRDTP_SERIALIZE_FIELD("idpLoginUrl", m_idpLoginUrl);
    CRDTP_SERIALIZE_FIELD("loginState", m_loginState);
    CRDTP_SERIALIZE_FIELD("termsOfServiceUrl", m_termsOfServiceUrl);
    CRDTP_SERIALIZE_FIELD("privacyPolicyUrl", m_privacyPolicyUrl);
CRDTP_END_SERIALIZER();


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


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

void Frontend::DialogShown(const String& dialogId, const String& dialogType, std::unique_ptr<protocol::Array<protocol::FedCm::Account>> accounts, const String& title, std::optional<String> subtitle)
{
    if (!frontend_channel_)
        return;
    crdtp::ObjectSerializer serializer;
    serializer.AddField(crdtp::MakeSpan("dialogId"), dialogId);
    serializer.AddField(crdtp::MakeSpan("dialogType"), dialogType);
    serializer.AddField(crdtp::MakeSpan("accounts"), accounts);
    serializer.AddField(crdtp::MakeSpan("title"), title);
    serializer.AddField(crdtp::MakeSpan("subtitle"), subtitle);
    frontend_channel_->SendProtocolNotification(crdtp::CreateNotification("FedCm.dialogShown", serializer.Finish()));
}

void Frontend::DialogClosed(const String& dialogId)
{
    if (!frontend_channel_)
        return;
    crdtp::ObjectSerializer serializer;
    serializer.AddField(crdtp::MakeSpan("dialogId"), dialogId);
    frontend_channel_->SendProtocolNotification(crdtp::CreateNotification("FedCm.dialogClosed", serializer.Finish()));
}

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 enable(crdtp::Dispatchable& dispatchable);
    void disable(crdtp::Dispatchable& dispatchable);
    void selectAccount(crdtp::Dispatchable& dispatchable);
    void clickDialogButton(crdtp::Dispatchable& dispatchable);
    void openUrl(crdtp::Dispatchable& dispatchable);
    void dismissDialog(crdtp::Dispatchable& dispatchable);
    void resetCooldown(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("clickDialogButton"),
          &DomainDispatcherImpl::clickDialogButton
    },
    {
          crdtp::SpanFrom("disable"),
          &DomainDispatcherImpl::disable
    },
    {
          crdtp::SpanFrom("dismissDialog"),
          &DomainDispatcherImpl::dismissDialog
    },
    {
          crdtp::SpanFrom("enable"),
          &DomainDispatcherImpl::enable
    },
    {
          crdtp::SpanFrom("openUrl"),
          &DomainDispatcherImpl::openUrl
    },
    {
          crdtp::SpanFrom("resetCooldown"),
          &DomainDispatcherImpl::resetCooldown
    },
    {
          crdtp::SpanFrom("selectAccount"),
          &DomainDispatcherImpl::selectAccount
    },
    };
    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 {

struct enableParams : public crdtp::DeserializableProtocolObject<enableParams> {
    std::optional<bool> disableRejectionDelay;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(enableParams)
    CRDTP_DESERIALIZE_FIELD_OPT("disableRejectionDelay", disableRejectionDelay),
CRDTP_END_DESERIALIZER()

}  // namespace

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

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

namespace {


}  // namespace

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

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

namespace {

struct selectAccountParams : public crdtp::DeserializableProtocolObject<selectAccountParams> {
    String dialogId;
    int accountIndex;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(selectAccountParams)
    CRDTP_DESERIALIZE_FIELD("accountIndex", accountIndex),
    CRDTP_DESERIALIZE_FIELD("dialogId", dialogId),
CRDTP_END_DESERIALIZER()

}  // namespace

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

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

namespace {

struct clickDialogButtonParams : public crdtp::DeserializableProtocolObject<clickDialogButtonParams> {
    String dialogId;
    String dialogButton;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(clickDialogButtonParams)
    CRDTP_DESERIALIZE_FIELD("dialogButton", dialogButton),
    CRDTP_DESERIALIZE_FIELD("dialogId", dialogId),
CRDTP_END_DESERIALIZER()

}  // namespace

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

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

namespace {

struct openUrlParams : public crdtp::DeserializableProtocolObject<openUrlParams> {
    String dialogId;
    int accountIndex;
    String accountUrlType;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(openUrlParams)
    CRDTP_DESERIALIZE_FIELD("accountIndex", accountIndex),
    CRDTP_DESERIALIZE_FIELD("accountUrlType", accountUrlType),
    CRDTP_DESERIALIZE_FIELD("dialogId", dialogId),
CRDTP_END_DESERIALIZER()

}  // namespace

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

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

namespace {

struct dismissDialogParams : public crdtp::DeserializableProtocolObject<dismissDialogParams> {
    String dialogId;
    std::optional<bool> triggerCooldown;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(dismissDialogParams)
    CRDTP_DESERIALIZE_FIELD("dialogId", dialogId),
    CRDTP_DESERIALIZE_FIELD_OPT("triggerCooldown", triggerCooldown),
CRDTP_END_DESERIALIZER()

}  // namespace

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

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

namespace {


}  // namespace

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

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->ResetCooldown();
    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("FedCm"), SortedRedirects(), std::move(dispatcher));
}

} // FedCm
} // namespace content
} // namespace protocol
