// This file is generated by DispatcherBase_cpp.template.

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

//#include "DispatcherBase.h"
//#include "Parser.h"

{% for namespace in config.protocol.namespace %}
namespace {{namespace}} {
{% endfor %}

// static
DispatchResponse DispatchResponse::OK()
{
    DispatchResponse result;
    result.m_status = kSuccess;
    result.m_errorCode = kParseError;
    return result;
}

// static
DispatchResponse DispatchResponse::Error(const String& error)
{
    DispatchResponse result;
    result.m_status = kError;
    result.m_errorCode = kServerError;
    result.m_errorMessage = error;
    return result;
}

// static
DispatchResponse DispatchResponse::InternalError()
{
    DispatchResponse result;
    result.m_status = kError;
    result.m_errorCode = kInternalError;
    result.m_errorMessage = "Internal error";
    return result;
}

// static
DispatchResponse DispatchResponse::InvalidParams(const String& error)
{
    DispatchResponse result;
    result.m_status = kError;
    result.m_errorCode = kInvalidParams;
    result.m_errorMessage = error;
    return result;
}

// static
DispatchResponse DispatchResponse::FallThrough()
{
    DispatchResponse result;
    result.m_status = kFallThrough;
    result.m_errorCode = kParseError;
    return result;
}

// static
const char DispatcherBase::kInvalidParamsString[] = "Invalid parameters";

DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { }

DispatcherBase::WeakPtr::~WeakPtr()
{
    if (m_dispatcher)
        m_dispatcher->m_weakPtrs.erase(this);
}

DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const ProtocolMessage& message)
    : m_backendImpl(std::move(backendImpl))
    , m_callId(callId)
    , m_method(method)
    , m_message(message) { }

DispatcherBase::Callback::~Callback() = default;

void DispatcherBase::Callback::dispose()
{
    m_backendImpl = nullptr;
}

void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response)
{
    if (!m_backendImpl || !m_backendImpl->get())
        return;
    m_backendImpl->get()->sendResponse(m_callId, response, std::move(partialMessage));
    m_backendImpl = nullptr;
}

void DispatcherBase::Callback::fallThroughIfActive()
{
    if (!m_backendImpl || !m_backendImpl->get())
        return;
    m_backendImpl->get()->channel()->fallThrough(m_callId, m_method, m_message);
    m_backendImpl = nullptr;
}

DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
    : m_frontendChannel(frontendChannel) { }

DispatcherBase::~DispatcherBase()
{
    clearFrontend();
}

void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
{
    if (!m_frontendChannel)
        return;
    if (response.status() == DispatchResponse::kError) {
        reportProtocolError(callId, response.errorCode(), response.errorMessage(), nullptr);
        return;
    }
    m_frontendChannel->sendProtocolResponse(callId, InternalResponse::createResponse(callId, std::move(result)));
}

void DispatcherBase::sendResponse(int callId, const DispatchResponse& response)
{
    sendResponse(callId, response, DictionaryValue::create());
}

namespace {

class ProtocolError : public Serializable {
public:
    static std::unique_ptr<ProtocolError> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
    {
        std::unique_ptr<ProtocolError> protocolError(new ProtocolError(code, errorMessage));
        protocolError->m_callId = callId;
        protocolError->m_hasCallId = true;
        if (errors && errors->hasErrors())
            protocolError->m_data = errors->errors();
        return protocolError;
    }

    static std::unique_ptr<ProtocolError> createErrorNotification(DispatchResponse::ErrorCode code, const String& errorMessage)
    {
        return std::unique_ptr<ProtocolError>(new ProtocolError(code, errorMessage));
    }

    String serializeToJSON() override
    {
        return serialize()->serializeToJSON();
    }

    std::vector<uint8_t> serializeToBinary() override
    {
        return serialize()->serializeToBinary();
    }

    ~ProtocolError() override {}

private:
    ProtocolError(DispatchResponse::ErrorCode code, const String& errorMessage)
        : m_code(code)
        , m_errorMessage(errorMessage)
    {
    }

    std::unique_ptr<DictionaryValue> serialize() {
        std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create();
        error->setInteger("code", m_code);
        error->setString("message", m_errorMessage);
        if (m_data.length())
            error->setString("data", m_data);
        std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create();
        message->setObject("error", std::move(error));
        if (m_hasCallId)
            message->setInteger("id", m_callId);
        return message;
    }

    DispatchResponse::ErrorCode m_code;
    String m_errorMessage;
    String m_data;
    int m_callId = 0;
    bool m_hasCallId = false;
};

} // namespace

static void reportProtocolErrorTo(FrontendChannel* frontendChannel, int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
{
    if (frontendChannel)
        frontendChannel->sendProtocolResponse(callId, ProtocolError::createErrorResponse(callId, code, errorMessage, errors));
}

static void reportProtocolErrorTo(FrontendChannel* frontendChannel, DispatchResponse::ErrorCode code, const String& errorMessage)
{
    if (frontendChannel)
        frontendChannel->sendProtocolNotification(ProtocolError::createErrorNotification(code, errorMessage));
}

void DispatcherBase::reportProtocolError(int callId, DispatchResponse::ErrorCode code, const String& errorMessage, ErrorSupport* errors)
{
    reportProtocolErrorTo(m_frontendChannel, callId, code, errorMessage, errors);
}

void DispatcherBase::clearFrontend()
{
    m_frontendChannel = nullptr;
    for (auto& weak : m_weakPtrs)
        weak->dispose();
    m_weakPtrs.clear();
}

std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
{
    std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this));
    m_weakPtrs.insert(weak.get());
    return weak;
}

UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
    : m_frontendChannel(frontendChannel) { }

void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
{
    m_dispatchers[name] = std::move(dispatcher);
}

void UberDispatcher::setupRedirects(const std::unordered_map<String, String>& redirects)
{
    for (const auto& pair : redirects)
        m_redirects[pair.first] = pair.second;
}

bool UberDispatcher::parseCommand(Value* parsedMessage, int* outCallId, String* outMethod) {
    if (!parsedMessage) {
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
        return false;
    }
    protocol::DictionaryValue* messageObject = DictionaryValue::cast(parsedMessage);
    if (!messageObject) {
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
        return false;
    }

    int callId = 0;
    protocol::Value* callIdValue = messageObject->get("id");
    bool success = callIdValue && callIdValue->asInteger(&callId);
    if (!success) {
        reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' property");
        return false;
    }
    if (outCallId)
      *outCallId = callId;

    protocol::Value* methodValue = messageObject->get("method");
    String method;
    success = methodValue && methodValue->asString(&method);
    if (!success) {
        reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' property", nullptr);
        return false;
    }
    if (outMethod)
      *outMethod = method;
    return true;
}

protocol::DispatcherBase* UberDispatcher::findDispatcher(const String& method) {
    size_t dotIndex = StringUtil::find(method, ".");
    if (dotIndex == StringUtil::kNotFound)
        return nullptr;
    String domain = StringUtil::substring(method, 0, dotIndex);
    auto it = m_dispatchers.find(domain);
    if (it == m_dispatchers.end())
        return nullptr;
    if (!it->second->canDispatch(method))
        return nullptr;
    return it->second.get();
}

bool UberDispatcher::canDispatch(const String& in_method)
{
    String method = in_method;
    auto redirectIt = m_redirects.find(method);
    if (redirectIt != m_redirects.end())
        method = redirectIt->second;
    return !!findDispatcher(method);
}

void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_ptr<Value> parsedMessage, const ProtocolMessage& rawMessage)
{
    String method = in_method;
    auto redirectIt = m_redirects.find(method);
    if (redirectIt != m_redirects.end())
        method = redirectIt->second;
    protocol::DispatcherBase* dispatcher = findDispatcher(method);
    if (!dispatcher) {
        reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
        return;
    }
    std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
    dispatcher->dispatch(callId, method, rawMessage, std::move(messageObject));
}

UberDispatcher::~UberDispatcher() = default;

// static
std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params)
{
    return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params)));
}

// static
std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params)
{
    return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params)));
}

String InternalResponse::serializeToJSON()
{
    std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
    std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
    if (m_notification.length()) {
        result->setString("method", m_notification);
        result->setValue("params", SerializedValue::fromJSON(params->serializeToJSON()));
    } else {
        result->setInteger("id", m_callId);
        result->setValue("result", SerializedValue::fromJSON(params->serializeToJSON()));
    }
    return result->serializeToJSON();
}

std::vector<uint8_t> InternalResponse::serializeToBinary()
{
    std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
    std::unique_ptr<Serializable> params(m_params ? std::move(m_params) : DictionaryValue::create());
    if (m_notification.length()) {
        result->setString("method", m_notification);
        result->setValue("params", SerializedValue::fromBinary(params->serializeToBinary()));
    } else {
        result->setInteger("id", m_callId);
        result->setValue("result", SerializedValue::fromBinary(params->serializeToBinary()));
    }
    return result->serializeToBinary();
}

InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr<Serializable> params)
    : m_callId(callId)
    , m_notification(notification)
    , m_params(params ? std::move(params) : nullptr)
{
}

{% for namespace in config.protocol.namespace %}
} // namespace {{namespace}}
{% endfor %}
