// 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/security.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 Security {

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

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

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




CRDTP_BEGIN_DESERIALIZER(CertificateSecurityState)
    CRDTP_DESERIALIZE_FIELD("certificate", m_certificate),
    CRDTP_DESERIALIZE_FIELD("certificateHasSha1Signature", m_certificateHasSha1Signature),
    CRDTP_DESERIALIZE_FIELD("certificateHasWeakSignature", m_certificateHasWeakSignature),
    CRDTP_DESERIALIZE_FIELD_OPT("certificateNetworkError", m_certificateNetworkError),
    CRDTP_DESERIALIZE_FIELD("cipher", m_cipher),
    CRDTP_DESERIALIZE_FIELD("issuer", m_issuer),
    CRDTP_DESERIALIZE_FIELD("keyExchange", m_keyExchange),
    CRDTP_DESERIALIZE_FIELD_OPT("keyExchangeGroup", m_keyExchangeGroup),
    CRDTP_DESERIALIZE_FIELD_OPT("mac", m_mac),
    CRDTP_DESERIALIZE_FIELD("modernSSL", m_modernSSL),
    CRDTP_DESERIALIZE_FIELD("obsoleteSslCipher", m_obsoleteSslCipher),
    CRDTP_DESERIALIZE_FIELD("obsoleteSslKeyExchange", m_obsoleteSslKeyExchange),
    CRDTP_DESERIALIZE_FIELD("obsoleteSslProtocol", m_obsoleteSslProtocol),
    CRDTP_DESERIALIZE_FIELD("obsoleteSslSignature", m_obsoleteSslSignature),
    CRDTP_DESERIALIZE_FIELD("protocol", m_protocol),
    CRDTP_DESERIALIZE_FIELD("subjectName", m_subjectName),
    CRDTP_DESERIALIZE_FIELD("validFrom", m_validFrom),
    CRDTP_DESERIALIZE_FIELD("validTo", m_validTo),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(CertificateSecurityState)
    CRDTP_SERIALIZE_FIELD("protocol", m_protocol);
    CRDTP_SERIALIZE_FIELD("keyExchange", m_keyExchange);
    CRDTP_SERIALIZE_FIELD("keyExchangeGroup", m_keyExchangeGroup);
    CRDTP_SERIALIZE_FIELD("cipher", m_cipher);
    CRDTP_SERIALIZE_FIELD("mac", m_mac);
    CRDTP_SERIALIZE_FIELD("certificate", m_certificate);
    CRDTP_SERIALIZE_FIELD("subjectName", m_subjectName);
    CRDTP_SERIALIZE_FIELD("issuer", m_issuer);
    CRDTP_SERIALIZE_FIELD("validFrom", m_validFrom);
    CRDTP_SERIALIZE_FIELD("validTo", m_validTo);
    CRDTP_SERIALIZE_FIELD("certificateNetworkError", m_certificateNetworkError);
    CRDTP_SERIALIZE_FIELD("certificateHasWeakSignature", m_certificateHasWeakSignature);
    CRDTP_SERIALIZE_FIELD("certificateHasSha1Signature", m_certificateHasSha1Signature);
    CRDTP_SERIALIZE_FIELD("modernSSL", m_modernSSL);
    CRDTP_SERIALIZE_FIELD("obsoleteSslProtocol", m_obsoleteSslProtocol);
    CRDTP_SERIALIZE_FIELD("obsoleteSslKeyExchange", m_obsoleteSslKeyExchange);
    CRDTP_SERIALIZE_FIELD("obsoleteSslCipher", m_obsoleteSslCipher);
    CRDTP_SERIALIZE_FIELD("obsoleteSslSignature", m_obsoleteSslSignature);
CRDTP_END_SERIALIZER();



CRDTP_BEGIN_DESERIALIZER(SafetyTipInfo)
    CRDTP_DESERIALIZE_FIELD_OPT("safeUrl", m_safeUrl),
    CRDTP_DESERIALIZE_FIELD("safetyTipStatus", m_safetyTipStatus),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(SafetyTipInfo)
    CRDTP_SERIALIZE_FIELD("safetyTipStatus", m_safetyTipStatus);
    CRDTP_SERIALIZE_FIELD("safeUrl", m_safeUrl);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(VisibleSecurityState)
    CRDTP_DESERIALIZE_FIELD_OPT("certificateSecurityState", m_certificateSecurityState),
    CRDTP_DESERIALIZE_FIELD_OPT("safetyTipInfo", m_safetyTipInfo),
    CRDTP_DESERIALIZE_FIELD("securityState", m_securityState),
    CRDTP_DESERIALIZE_FIELD("securityStateIssueIds", m_securityStateIssueIds),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(VisibleSecurityState)
    CRDTP_SERIALIZE_FIELD("securityState", m_securityState);
    CRDTP_SERIALIZE_FIELD("certificateSecurityState", m_certificateSecurityState);
    CRDTP_SERIALIZE_FIELD("safetyTipInfo", m_safetyTipInfo);
    CRDTP_SERIALIZE_FIELD("securityStateIssueIds", m_securityStateIssueIds);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(SecurityStateExplanation)
    CRDTP_DESERIALIZE_FIELD("certificate", m_certificate),
    CRDTP_DESERIALIZE_FIELD("description", m_description),
    CRDTP_DESERIALIZE_FIELD("mixedContentType", m_mixedContentType),
    CRDTP_DESERIALIZE_FIELD_OPT("recommendations", m_recommendations),
    CRDTP_DESERIALIZE_FIELD("securityState", m_securityState),
    CRDTP_DESERIALIZE_FIELD("summary", m_summary),
    CRDTP_DESERIALIZE_FIELD("title", m_title),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(SecurityStateExplanation)
    CRDTP_SERIALIZE_FIELD("securityState", m_securityState);
    CRDTP_SERIALIZE_FIELD("title", m_title);
    CRDTP_SERIALIZE_FIELD("summary", m_summary);
    CRDTP_SERIALIZE_FIELD("description", m_description);
    CRDTP_SERIALIZE_FIELD("mixedContentType", m_mixedContentType);
    CRDTP_SERIALIZE_FIELD("certificate", m_certificate);
    CRDTP_SERIALIZE_FIELD("recommendations", m_recommendations);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(InsecureContentStatus)
    CRDTP_DESERIALIZE_FIELD("containedMixedForm", m_containedMixedForm),
    CRDTP_DESERIALIZE_FIELD("displayedContentWithCertErrors", m_displayedContentWithCertErrors),
    CRDTP_DESERIALIZE_FIELD("displayedInsecureContentStyle", m_displayedInsecureContentStyle),
    CRDTP_DESERIALIZE_FIELD("displayedMixedContent", m_displayedMixedContent),
    CRDTP_DESERIALIZE_FIELD("ranContentWithCertErrors", m_ranContentWithCertErrors),
    CRDTP_DESERIALIZE_FIELD("ranInsecureContentStyle", m_ranInsecureContentStyle),
    CRDTP_DESERIALIZE_FIELD("ranMixedContent", m_ranMixedContent),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(InsecureContentStatus)
    CRDTP_SERIALIZE_FIELD("ranMixedContent", m_ranMixedContent);
    CRDTP_SERIALIZE_FIELD("displayedMixedContent", m_displayedMixedContent);
    CRDTP_SERIALIZE_FIELD("containedMixedForm", m_containedMixedForm);
    CRDTP_SERIALIZE_FIELD("ranContentWithCertErrors", m_ranContentWithCertErrors);
    CRDTP_SERIALIZE_FIELD("displayedContentWithCertErrors", m_displayedContentWithCertErrors);
    CRDTP_SERIALIZE_FIELD("ranInsecureContentStyle", m_ranInsecureContentStyle);
    CRDTP_SERIALIZE_FIELD("displayedInsecureContentStyle", m_displayedInsecureContentStyle);
CRDTP_END_SERIALIZER();



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


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

void Frontend::CertificateError(int eventId, const String& errorType, const String& requestURL)
{
    if (!frontend_channel_)
        return;
    crdtp::ObjectSerializer serializer;
    serializer.AddField(crdtp::MakeSpan("eventId"), eventId);
    serializer.AddField(crdtp::MakeSpan("errorType"), errorType);
    serializer.AddField(crdtp::MakeSpan("requestURL"), requestURL);
    frontend_channel_->SendProtocolNotification(crdtp::CreateNotification("Security.certificateError", serializer.Finish()));
}

void Frontend::VisibleSecurityStateChanged(std::unique_ptr<protocol::Security::VisibleSecurityState> visibleSecurityState)
{
    if (!frontend_channel_)
        return;
    crdtp::ObjectSerializer serializer;
    serializer.AddField(crdtp::MakeSpan("visibleSecurityState"), visibleSecurityState);
    frontend_channel_->SendProtocolNotification(crdtp::CreateNotification("Security.visibleSecurityStateChanged", serializer.Finish()));
}

void Frontend::SecurityStateChanged(const String& securityState, bool schemeIsCryptographic, std::unique_ptr<protocol::Array<protocol::Security::SecurityStateExplanation>> explanations, std::unique_ptr<protocol::Security::InsecureContentStatus> insecureContentStatus, std::optional<String> summary)
{
    if (!frontend_channel_)
        return;
    crdtp::ObjectSerializer serializer;
    serializer.AddField(crdtp::MakeSpan("securityState"), securityState);
    serializer.AddField(crdtp::MakeSpan("schemeIsCryptographic"), schemeIsCryptographic);
    serializer.AddField(crdtp::MakeSpan("explanations"), explanations);
    serializer.AddField(crdtp::MakeSpan("insecureContentStatus"), insecureContentStatus);
    serializer.AddField(crdtp::MakeSpan("summary"), summary);
    frontend_channel_->SendProtocolNotification(crdtp::CreateNotification("Security.securityStateChanged", 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 disable(crdtp::Dispatchable& dispatchable);
    void enable(crdtp::Dispatchable& dispatchable);
    void setIgnoreCertificateErrors(crdtp::Dispatchable& dispatchable);
    void handleCertificateError(crdtp::Dispatchable& dispatchable);
    void setOverrideCertificateErrors(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("disable"),
          &DomainDispatcherImpl::disable
    },
    {
          crdtp::SpanFrom("enable"),
          &DomainDispatcherImpl::enable
    },
    {
          crdtp::SpanFrom("handleCertificateError"),
          &DomainDispatcherImpl::handleCertificateError
    },
    {
          crdtp::SpanFrom("setIgnoreCertificateErrors"),
          &DomainDispatcherImpl::setIgnoreCertificateErrors
    },
    {
          crdtp::SpanFrom("setOverrideCertificateErrors"),
          &DomainDispatcherImpl::setOverrideCertificateErrors
    },
    };
    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::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 {


}  // namespace

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

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

namespace {

struct setIgnoreCertificateErrorsParams : public crdtp::DeserializableProtocolObject<setIgnoreCertificateErrorsParams> {
    bool ignore;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setIgnoreCertificateErrorsParams)
    CRDTP_DESERIALIZE_FIELD("ignore", ignore),
CRDTP_END_DESERIALIZER()

}  // namespace

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

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

namespace {

struct handleCertificateErrorParams : public crdtp::DeserializableProtocolObject<handleCertificateErrorParams> {
    int eventId;
    String action;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(handleCertificateErrorParams)
    CRDTP_DESERIALIZE_FIELD("action", action),
    CRDTP_DESERIALIZE_FIELD("eventId", eventId),
CRDTP_END_DESERIALIZER()

}  // namespace

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

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

namespace {

struct setOverrideCertificateErrorsParams : public crdtp::DeserializableProtocolObject<setOverrideCertificateErrorsParams> {
    bool override;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setOverrideCertificateErrorsParams)
    CRDTP_DESERIALIZE_FIELD("override", override),
CRDTP_END_DESERIALIZER()

}  // namespace

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

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

} // Security
} // namespace content
} // namespace protocol
