// 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/system_info.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 SystemInfo {

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

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

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

CRDTP_BEGIN_DESERIALIZER(GPUDevice)
    CRDTP_DESERIALIZE_FIELD("deviceId", m_deviceId),
    CRDTP_DESERIALIZE_FIELD("deviceString", m_deviceString),
    CRDTP_DESERIALIZE_FIELD("driverVendor", m_driverVendor),
    CRDTP_DESERIALIZE_FIELD("driverVersion", m_driverVersion),
    CRDTP_DESERIALIZE_FIELD_OPT("revision", m_revision),
    CRDTP_DESERIALIZE_FIELD_OPT("subSysId", m_subSysId),
    CRDTP_DESERIALIZE_FIELD("vendorId", m_vendorId),
    CRDTP_DESERIALIZE_FIELD("vendorString", m_vendorString),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(GPUDevice)
    CRDTP_SERIALIZE_FIELD("vendorId", m_vendorId);
    CRDTP_SERIALIZE_FIELD("deviceId", m_deviceId);
    CRDTP_SERIALIZE_FIELD("subSysId", m_subSysId);
    CRDTP_SERIALIZE_FIELD("revision", m_revision);
    CRDTP_SERIALIZE_FIELD("vendorString", m_vendorString);
    CRDTP_SERIALIZE_FIELD("deviceString", m_deviceString);
    CRDTP_SERIALIZE_FIELD("driverVendor", m_driverVendor);
    CRDTP_SERIALIZE_FIELD("driverVersion", m_driverVersion);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(Size)
    CRDTP_DESERIALIZE_FIELD("height", m_height),
    CRDTP_DESERIALIZE_FIELD("width", m_width),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(Size)
    CRDTP_SERIALIZE_FIELD("width", m_width);
    CRDTP_SERIALIZE_FIELD("height", m_height);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(VideoDecodeAcceleratorCapability)
    CRDTP_DESERIALIZE_FIELD("maxResolution", m_maxResolution),
    CRDTP_DESERIALIZE_FIELD("minResolution", m_minResolution),
    CRDTP_DESERIALIZE_FIELD("profile", m_profile),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(VideoDecodeAcceleratorCapability)
    CRDTP_SERIALIZE_FIELD("profile", m_profile);
    CRDTP_SERIALIZE_FIELD("maxResolution", m_maxResolution);
    CRDTP_SERIALIZE_FIELD("minResolution", m_minResolution);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(VideoEncodeAcceleratorCapability)
    CRDTP_DESERIALIZE_FIELD("maxFramerateDenominator", m_maxFramerateDenominator),
    CRDTP_DESERIALIZE_FIELD("maxFramerateNumerator", m_maxFramerateNumerator),
    CRDTP_DESERIALIZE_FIELD("maxResolution", m_maxResolution),
    CRDTP_DESERIALIZE_FIELD("profile", m_profile),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(VideoEncodeAcceleratorCapability)
    CRDTP_SERIALIZE_FIELD("profile", m_profile);
    CRDTP_SERIALIZE_FIELD("maxResolution", m_maxResolution);
    CRDTP_SERIALIZE_FIELD("maxFramerateNumerator", m_maxFramerateNumerator);
    CRDTP_SERIALIZE_FIELD("maxFramerateDenominator", m_maxFramerateDenominator);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(GPUInfo)
    CRDTP_DESERIALIZE_FIELD_OPT("auxAttributes", m_auxAttributes),
    CRDTP_DESERIALIZE_FIELD("devices", m_devices),
    CRDTP_DESERIALIZE_FIELD("driverBugWorkarounds", m_driverBugWorkarounds),
    CRDTP_DESERIALIZE_FIELD_OPT("featureStatus", m_featureStatus),
    CRDTP_DESERIALIZE_FIELD("videoDecoding", m_videoDecoding),
    CRDTP_DESERIALIZE_FIELD("videoEncoding", m_videoEncoding),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(GPUInfo)
    CRDTP_SERIALIZE_FIELD("devices", m_devices);
    CRDTP_SERIALIZE_FIELD("auxAttributes", m_auxAttributes);
    CRDTP_SERIALIZE_FIELD("featureStatus", m_featureStatus);
    CRDTP_SERIALIZE_FIELD("driverBugWorkarounds", m_driverBugWorkarounds);
    CRDTP_SERIALIZE_FIELD("videoDecoding", m_videoDecoding);
    CRDTP_SERIALIZE_FIELD("videoEncoding", m_videoEncoding);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(ProcessInfo)
    CRDTP_DESERIALIZE_FIELD("cpuTime", m_cpuTime),
    CRDTP_DESERIALIZE_FIELD("id", m_id),
    CRDTP_DESERIALIZE_FIELD("type", m_type),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(ProcessInfo)
    CRDTP_SERIALIZE_FIELD("type", m_type);
    CRDTP_SERIALIZE_FIELD("id", m_id);
    CRDTP_SERIALIZE_FIELD("cpuTime", m_cpuTime);
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 getInfo(crdtp::Dispatchable& dispatchable);
    void getFeatureState(crdtp::Dispatchable& dispatchable);
    void getProcessInfo(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("getFeatureState"),
          &DomainDispatcherImpl::getFeatureState
    },
    {
          crdtp::SpanFrom("getInfo"),
          &DomainDispatcherImpl::getInfo
    },
    {
          crdtp::SpanFrom("getProcessInfo"),
          &DomainDispatcherImpl::getProcessInfo
    },
    };
    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;
}


class GetInfoCallbackImpl : public Backend::GetInfoCallback, public DomainDispatcher::Callback {
public:
    GetInfoCallbackImpl(std::unique_ptr<DomainDispatcher::WeakPtr> backendImpl, crdtp::Dispatchable& dispatchable)
        : DomainDispatcher::Callback(std::move(backendImpl), dispatchable, crdtp::SpanFrom("SystemInfo.getInfo")) { }

    void sendSuccess(std::unique_ptr<protocol::SystemInfo::GPUInfo> gpu, const String& modelName, const String& modelVersion, const String& commandLine) override
    {
        crdtp::ObjectSerializer serializer;
        serializer.AddField(crdtp::MakeSpan("gpu"), gpu);
        serializer.AddField(crdtp::MakeSpan("modelName"), modelName);
        serializer.AddField(crdtp::MakeSpan("modelVersion"), modelVersion);
        serializer.AddField(crdtp::MakeSpan("commandLine"), commandLine);
        sendIfActive(serializer.Finish(), DispatchResponse::Success());
    }

    void fallThrough() override
    {
        fallThroughIfActive();
    }

    void sendFailure(const DispatchResponse& response) override
    {
        DCHECK(response.IsError());
        sendIfActive(nullptr, response);
    }
};

namespace {


}  // namespace

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

    m_backend->GetInfo(std::make_unique<GetInfoCallbackImpl>(weakPtr(), dispatchable));
}

namespace {

struct getFeatureStateParams : public crdtp::DeserializableProtocolObject<getFeatureStateParams> {
    String featureState;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(getFeatureStateParams)
    CRDTP_DESERIALIZE_FIELD("featureState", featureState),
CRDTP_END_DESERIALIZER()

}  // namespace

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

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->GetFeatureState(params.featureState, &out_featureEnabled);
    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("featureEnabled"), out_featureEnabled);
          result = serializer.Finish();
        } else {
          result = Serializable::From({});
        }
        weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result));
      }
    return;
}

class GetProcessInfoCallbackImpl : public Backend::GetProcessInfoCallback, public DomainDispatcher::Callback {
public:
    GetProcessInfoCallbackImpl(std::unique_ptr<DomainDispatcher::WeakPtr> backendImpl, crdtp::Dispatchable& dispatchable)
        : DomainDispatcher::Callback(std::move(backendImpl), dispatchable, crdtp::SpanFrom("SystemInfo.getProcessInfo")) { }

    void sendSuccess(std::unique_ptr<protocol::Array<protocol::SystemInfo::ProcessInfo>> processInfo) override
    {
        crdtp::ObjectSerializer serializer;
        serializer.AddField(crdtp::MakeSpan("processInfo"), processInfo);
        sendIfActive(serializer.Finish(), DispatchResponse::Success());
    }

    void fallThrough() override
    {
        fallThroughIfActive();
    }

    void sendFailure(const DispatchResponse& response) override
    {
        DCHECK(response.IsError());
        sendIfActive(nullptr, response);
    }
};

namespace {


}  // namespace

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

    m_backend->GetProcessInfo(std::make_unique<GetProcessInfoCallbackImpl>(weakPtr(), dispatchable));
}

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("SystemInfo"), SortedRedirects(), std::move(dispatcher));
}

} // SystemInfo
} // namespace content
} // namespace protocol
