// This file is generated by TypeBuilder_h.template.

// Copyright (c) 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.

#ifndef {{"_".join(config.protocol.namespace)}}_{{domain.domain}}_h
#define {{"_".join(config.protocol.namespace)}}_{{domain.domain}}_h

{% if config.protocol.export_header %}
#include {{format_include(config.protocol.export_header)}}
{% endif %}
#include {{format_include(config.protocol.package, "Protocol")}}
// For each imported domain we generate a ValueConversions struct instead of a full domain definition
// and include Domain::API version from there.
{% for name in domain.dependencies %}
  {% if protocol.is_imported_dependency(name) %}
#include {{format_domain_include(config.protocol.package, name)}}
  {% endif %}
{% endfor %}
{% if protocol.is_exported_domain(domain.domain) %}
#include {{format_include(config.exported.package, domain.domain)}}
{% endif %}

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

// ------------- Forward and enum declarations.
  {% for type in domain.types %}
    {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %}
    {% if type.type == "object" %}
      {% if "properties" in type %}
class {{type.id}};
      {% else %}
using {{type.id}} = Object;
      {% endif %}
    {% elif type.type != "array" %}
using {{type.id}} = {{protocol.resolve_type(type).type}};
    {% endif %}
  {% endfor %}
  {% for type in domain.types %}
    {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %}
    {% if "enum" in type %}

namespace {{type.id}}Enum {
      {% for literal in type.enum %}
{{config.protocol.export_macro}} extern const char {{ literal | dash_to_camelcase}}[];
      {% endfor %}
} // namespace {{type.id}}Enum
    {% endif %}
  {% endfor %}
  {% for command in join_arrays(domain, ["commands", "events"]) %}
    {% for param in join_arrays(command, ["parameters", "returns"]) %}
      {% if "enum" in param %}

namespace {{command.name | to_title_case}} {
namespace {{param.name | to_title_case}}Enum {
        {% for literal in param.enum %}
{{config.protocol.export_macro}} extern const char* {{literal | dash_to_camelcase}};
        {% endfor %}
} // {{param.name | to_title_case}}Enum
} // {{command.name | to_title_case }}
      {% endif %}
    {% endfor %}
  {% endfor %}

// ------------- Type and builder declarations.
  {% for type in domain.types %}
    {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %}
    {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %}

class {{config.protocol.export_macro}} {{type.id}} : public Serializable{% if protocol.is_exported(domain.domain, type.id) %}, public API::{{type.id}}{% endif %}{
    PROTOCOL_DISALLOW_COPY({{type.id}});
public:
    static std::unique_ptr<{{type.id}}> fromValue(protocol::Value* value, ErrorSupport* errors);

    ~{{type.id}}() override { }
    {% for property in type.properties %}
      {% set property_type = protocol.resolve_type(property) %}
      {% set property_name = property.name | to_title_case %}
      {% set property_field = "m_" + property.name %}
      {% if "enum" in property %}

    struct {{config.protocol.export_macro}} {{property_name}}Enum {
        {% for literal in property.enum %}
        static const char* {{literal | dash_to_camelcase}};
        {% endfor %}
    }; // {{property_name}}Enum
      {% endif %}

      {% if property.optional %}
    bool {{"has" | to_method_case}}{{property_name}}() { return {{property_field}}.isJust(); }
    {{property_type.raw_return_type}} {{"get" | to_method_case}}{{property_name}}({{property_type.raw_pass_type}} defaultValue) { return {{property_field}}.isJust() ? {{property_field}}.fromJust() : defaultValue; }
      {% else %}
    {{property_type.raw_return_type}} {{"get" | to_method_case}}{{property_name}}() { return {{property_type.to_raw_type % property_field}}; }
      {% endif %}
    void {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value) { {{property_field}} = {{property_type.to_rvalue % "value"}}; }
    {% endfor %}

    std::unique_ptr<protocol::DictionaryValue> toValue() const;
    void AppendSerialized(std::vector<uint8_t>* out) const override {
        toValue()->AppendSerialized(out);
    }
    String toJSON() const { return toValue()->toJSONString(); }
    std::unique_ptr<{{type.id}}> clone() const;
    {% if protocol.is_exported(domain.domain, type.id) %}
    {{config.exported.string_out}} toJSONString() const override;
    void writeBinary(std::vector<uint8_t>* out) const override;
    {% endif %}

    template<int STATE>
    class {{type.id}}Builder {
    public:
        enum {
            NoFieldsSet = 0,
    {% for property in type.properties|rejectattr("optional") %}
            {{property.name | to_title_case}}Set = 1 << {{loop.index}},
    {% endfor %}
            AllFieldsSet = (
    {%- for property in type.properties %}
      {% if not(property.optional) %}{{property.name | to_title_case}}Set | {%endif %}
    {% endfor %}0)};

    {% for property in type.properties %}
      {% set property_type = protocol.resolve_type(property) %}
      {% set property_name = property.name | to_title_case %}

      {% if property.optional %}
        {{type.id}}Builder<STATE>& {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value)
        {
            m_result->{{"set" | to_method_case}}{{property_name}}({{property_type.to_rvalue % "value"}});
            return *this;
        }
      {% else %}
        {{type.id}}Builder<STATE | {{property_name}}Set>& {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value)
        {
            static_assert(!(STATE & {{property_name}}Set), "property {{property.name}} should not be set yet");
            m_result->{{"set" | to_method_case}}{{property_name}}({{property_type.to_rvalue % "value"}});
            return castState<{{property_name}}Set>();
        }
      {% endif %}
    {% endfor %}

        std::unique_ptr<{{type.id}}> {{"build" | to_method_case}}()
        {
            static_assert(STATE == AllFieldsSet, "state should be AllFieldsSet");
            return std::move(m_result);
        }

    private:
        friend class {{type.id}};
        {{type.id}}Builder() : m_result(new {{type.id}}()) { }

        template<int STEP> {{type.id}}Builder<STATE | STEP>& castState()
        {
            return *reinterpret_cast<{{type.id}}Builder<STATE | STEP>*>(this);
        }

        {{protocol.type_definition(domain.domain + "." + type.id).type}} m_result;
    };

    static {{type.id}}Builder<0> {{"create" | to_method_case}}()
    {
        return {{type.id}}Builder<0>();
    }

private:
    {{type.id}}()
    {
    {% for property in type.properties %}
      {% if not(property.optional) and "default_value" in protocol.resolve_type(property) %}
          m_{{property.name}} = {{protocol.resolve_type(property).default_value}};
      {%endif %}
    {% endfor %}
    }

    {% for property in type.properties %}
      {% if property.optional %}
    Maybe<{{protocol.resolve_type(property).raw_type}}> m_{{property.name}};
      {% else %}
    {{protocol.resolve_type(property).type}} m_{{property.name}};
      {% endif %}
    {% endfor %}
};

  {% endfor %}

// ------------- Backend interface.

class {{config.protocol.export_macro}} Backend {
public:
    virtual ~Backend() { }

  {% for command in domain.commands %}
    {% if "redirect" in command %}{% continue %}{% endif %}
    {% if not protocol.generate_command(domain.domain, command.name) %}{% continue %}{% endif %}
    {% if protocol.is_async_command(domain.domain, command.name) %}
    class {{config.protocol.export_macro}} {{command.name | to_title_case}}Callback {
    public:
        virtual void sendSuccess(
      {%- for parameter in command.returns -%}
        {%- if "optional" in parameter -%}
            Maybe<{{protocol.resolve_type(parameter).raw_type}}> {{parameter.name}}
        {%- else -%}
                {{protocol.resolve_type(parameter).pass_type}} {{parameter.name}}
        {%- endif -%}
        {%- if not loop.last -%}, {% endif -%}
      {%- endfor -%}
        ) = 0;
        virtual void sendFailure(const DispatchResponse&) = 0;
        virtual void fallThrough() = 0;
        virtual ~{{command.name | to_title_case}}Callback() { }
    };
    {% endif %}
    {%- if not protocol.is_async_command(domain.domain, command.name) %}
    virtual DispatchResponse {{command.name | to_method_case}}(
    {%- else %}
    virtual void {{command.name | to_method_case}}(
    {%- endif %}
    {%- for parameter in command.parameters -%}
      {%- if not loop.first -%}, {% endif -%}
      {%- if "optional" in parameter -%}
        Maybe<{{protocol.resolve_type(parameter).raw_type}}> in_{{parameter.name}}
      {%- else -%}
        {{protocol.resolve_type(parameter).pass_type}} in_{{parameter.name}}
      {%- endif -%}
    {%- endfor -%}
    {%- if protocol.is_async_command(domain.domain, command.name) -%}
      {%- if command.parameters -%}, {% endif -%}
        std::unique_ptr<{{command.name | to_title_case}}Callback> callback
    {%- else -%}
      {%- for parameter in command.returns -%}
        {%- if (not loop.first) or command.parameters -%}, {% endif -%}
        {%- if "optional" in parameter -%}
        Maybe<{{protocol.resolve_type(parameter).raw_type}}>* out_{{parameter.name}}
        {%- else -%}
        {{protocol.resolve_type(parameter).type}}* out_{{parameter.name}}
        {%- endif -%}
      {%- endfor -%}
    {%- endif -%}
    ) = 0;
  {% endfor %}

  {% if protocol.generate_disable(domain) %}
    virtual DispatchResponse {{"disable" | to_method_case}}()
    {
        return DispatchResponse::OK();
    }
  {% endif %}
};

// ------------- Frontend interface.

class {{config.protocol.export_macro}} Frontend {
public:
    explicit Frontend(FrontendChannel* frontendChannel) : m_frontendChannel(frontendChannel) { }
  {% for event in domain.events %}
    {% if not protocol.generate_event(domain.domain, event.name) %}{% continue %}{% endif %}
    void {{event.name | to_method_case}}(
    {%- for parameter in event.parameters -%}
      {%- if "optional" in parameter -%}
        Maybe<{{protocol.resolve_type(parameter).raw_type}}> {{parameter.name}} = Maybe<{{protocol.resolve_type(parameter).raw_type}}>()
      {%- else -%}
        {{protocol.resolve_type(parameter).pass_type}} {{parameter.name}}
      {%- endif -%}{%- if not loop.last -%}, {% endif -%}
    {%- endfor -%}
    );
  {% endfor %}

    void flush();
    void sendRawCBORNotification(std::vector<uint8_t>);
private:
    FrontendChannel* m_frontendChannel;
};

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

class {{config.protocol.export_macro}} Dispatcher {
public:
    static void wire(UberDispatcher*, Backend*);

private:
    Dispatcher() { }
};

// ------------- Metainfo.

class {{config.protocol.export_macro}} Metainfo {
public:
    using BackendClass = Backend;
    using FrontendClass = Frontend;
    using DispatcherClass = Dispatcher;
    static const char domainName[];
    static const char commandPrefix[];
    static const char version[];
};

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

#endif // !defined({{"_".join(config.protocol.namespace)}}_{{domain.domain}}_h)
