{% from "constant_definition.tmpl" import constant_def %}
{% from "enum_definition.tmpl" import enum_def %}
{% from "data_types_definition.tmpl" import struct_def %}

{%- macro declare_params(parameters, boxed=false) %}
{%-   for param in parameters -%}
{{param.kind|java_type(boxed)}} {{param|name}}
{%- if not loop.last %}, {% endif %}
{%-   endfor %}
{%- endmacro %}

{% macro declare_request_params(method) %}
{{declare_params(method.parameters)}}
{%-   if method.response_parameters != None -%}
{%- if method.parameters %}, {% endif %}
{{method|interface_response_name}} callback
{%-   endif -%}
{% endmacro %}

{%- macro declare_callback(method) -%}

interface {{method|interface_response_name}} extends org.chromium.mojo.bindings.Callbacks.Callback{{method.response_parameters|length}}{% if method.response_parameters %}<
{%-   for param in method.response_parameters -%}
{{param.kind|java_type(True)}}
{%- if not loop.last %}, {% endif %}
{%-   endfor -%}
>{% endif %} { }
{%- endmacro -%}

{%- macro run_callback(variable, parameters) -%}
{%-   if parameters -%}
{%-     for param in parameters -%}
{{variable}}.{{param|name}}
{%-   if not loop.last %}, {% endif %}
{%-     endfor -%}
{%-   endif -%}
{%- endmacro -%}

{%- macro flags_for_method(method, is_request) -%}
{{flags(method.response_parameters != None, is_request)}}
{%- endmacro -%}

{%- macro flags(use_response_flag, is_request) -%}
{%-  if not use_response_flag -%}
org.chromium.mojo.bindings.MessageHeader.NO_FLAG
{%-   elif is_request: -%}
org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG
{%-   else -%}
org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG
{%-   endif -%}
{%- endmacro -%}

{%- macro manager_class(interface, fully_qualified=False) -%}
{% if fully_qualified %}org.chromium.mojo.bindings.Interface.{% endif %}{% if interface.service_name %}Named{% endif %}Manager<{{interface|name}}, {{interface|name}}.Proxy>
{%- endmacro -%}

{%- macro manager_def(interface) -%}
public static final {{manager_class(interface, True)}} MANAGER =
        new {{manager_class(interface, True)}}() {
{% if interface.service_name %}

    public String getName() {
        return "{{interface.service_name}}";
    }
{% endif %}

    public int getVersion() {
      return {{interface.version}};
    }

    public Proxy buildProxy(org.chromium.mojo.system.Core core,
                            org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
        return new Proxy(core, messageReceiver);
    }

    public Stub buildStub(org.chromium.mojo.system.Core core, {{interface|name}} impl) {
        return new Stub(core, impl);
    }

    public {{interface|name}}[] buildArray(int size) {
      return new {{interface|name}}[size];
    }
};
{%- endmacro -%}

{%- macro accept_body(interface, with_response) -%}
try {
    org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
            message.asServiceMessage();
    org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
    if (!header.validateHeader({{flags(with_response, True)}})) {
        return false;
    }
    switch(header.getType()) {
{%   if with_response %}
        case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_MESSAGE_ID:
            return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRun(
                    getCore(), {{interface|name}}_Internal.MANAGER, messageWithHeader, receiver);
{%   else %}
        case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_OR_CLOSE_PIPE_MESSAGE_ID:
            return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRunOrClosePipe(
                    {{interface|name}}_Internal.MANAGER, messageWithHeader);
{%   endif %}
{%   for method in interface.methods %}
{%     if (with_response and method.response_parameters != None) or
        (not with_response and method.response_parameters == None) %}
{%       set request_struct = method.param_struct %}
{%       if with_response %}
{%         set response_struct = method.response_param_struct %}
{%       endif %}
        case {{method|method_ordinal_name}}: {
{%       if method.parameters %}
            {{request_struct|name}} data =
                    {{request_struct|name}}.deserialize(messageWithHeader.getPayload());
{%       else %}
            {{request_struct|name}}.deserialize(messageWithHeader.getPayload());
{%       endif %}
            getImpl().{{method|name}}({{run_callback('data', method.parameters)}}{% if with_response %}{% if method.parameters %}, {% endif %}new {{response_struct|name}}ProxyToResponder(getCore(), receiver, header.getRequestId()){% endif %});
            return true;
        }
{%     endif %}
{%   endfor %}
        default:
            return false;
    }
} catch (org.chromium.mojo.bindings.DeserializationException e) {
    System.err.println(e.toString());
    return false;
}
{%- endmacro -%}

{% macro interface_def(interface) %}
public interface {{interface|name}} extends org.chromium.mojo.bindings.Interface {
{%  for constant in interface.constants %}

    {{constant_def(constant)|indent(4)}}
{%  endfor %}
{%  for enum in interface.enums %}

    {{enum_def(enum, false)|indent(4)}}
{% endfor %}

    public interface Proxy extends {{interface|name}}, org.chromium.mojo.bindings.Interface.Proxy {
    }

    {{manager_class(interface)}} MANAGER = {{interface|name}}_Internal.MANAGER;
{% for method in interface.methods %}

    void {{method|name}}({{declare_request_params(method)}});
{%   if method.response_parameters != None %}
    {{declare_callback(method)|indent(4)}}
{%   endif %}
{% endfor %}
}
{% endmacro %}

{% macro interface_internal_def(interface) %}
class {{interface|name}}_Internal {

    {{manager_def(interface)|indent(4)}}

{% for method in interface.methods %}
    private static final int {{method|method_ordinal_name}} = {{method.ordinal}};
{% endfor %}

    static final class Proxy extends org.chromium.mojo.bindings.Interface.AbstractProxy implements {{interface|name}}.Proxy {

        Proxy(org.chromium.mojo.system.Core core,
              org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
            super(core, messageReceiver);
        }
{% for method in interface.methods %}

        @Override
        public void {{method|name}}({{declare_request_params(method)}}) {
{%   set request_struct = method.param_struct %}
            {{request_struct|name}} _message = new {{request_struct|name}}();
{%   for param in method.parameters %}
            _message.{{param|name}} = {{param|name}};
{%   endfor %}
{%   if method.response_parameters != None %}
            getProxyHandler().getMessageReceiver().acceptWithResponder(
                    _message.serializeWithHeader(
                            getProxyHandler().getCore(),
                            new org.chromium.mojo.bindings.MessageHeader(
                                    {{method|method_ordinal_name}},
                                    {{flags_for_method(method, True)}},
                                    0)),
                    new {{method.response_param_struct|name}}ForwardToCallback(callback));
{%   else %}
            getProxyHandler().getMessageReceiver().accept(
                    _message.serializeWithHeader(
                            getProxyHandler().getCore(),
                            new org.chromium.mojo.bindings.MessageHeader({{method|method_ordinal_name}})));
{%   endif %}
        }
{% endfor %}

    }

    static final class Stub extends org.chromium.mojo.bindings.Interface.Stub<{{interface|name}}> {

        Stub(org.chromium.mojo.system.Core core, {{interface|name}} impl) {
            super(core, impl);
        }

        @Override
        public boolean accept(org.chromium.mojo.bindings.Message message) {
            {{accept_body(interface, False)|indent(12)}}
        }

        @Override
        public boolean acceptWithResponder(org.chromium.mojo.bindings.Message message, org.chromium.mojo.bindings.MessageReceiver receiver) {
            {{accept_body(interface, True)|indent(12)}}
        }
    }
{% for method in interface.methods %}

    {{ struct_def(method.param_struct, True)|indent(4) }}
{%   if method.response_parameters != None %}
{%   set response_struct = method.response_param_struct %}

    {{ struct_def(response_struct, True)|indent(4) }}

    static class {{response_struct|name}}ForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
            implements org.chromium.mojo.bindings.MessageReceiver {
        private final {{interface|name}}.{{method|interface_response_name}} mCallback;

        {{response_struct|name}}ForwardToCallback({{interface|name}}.{{method|interface_response_name}} callback) {
            this.mCallback = callback;
        }

        @Override
        public boolean accept(org.chromium.mojo.bindings.Message message) {
            try {
                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
                        message.asServiceMessage();
                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
                if (!header.validateHeader({{method|method_ordinal_name}},
                                           {{flags_for_method(method, False)}})) {
                    return false;
                }
{%   if method.response_parameters|length %}
                {{response_struct|name}} response = {{response_struct|name}}.deserialize(messageWithHeader.getPayload());
{%   endif %}
                mCallback.call({{run_callback('response', method.response_parameters)}});
                return true;
            } catch (org.chromium.mojo.bindings.DeserializationException e) {
                return false;
            }
        }
    }

    static class {{response_struct|name}}ProxyToResponder implements {{interface|name}}.{{method|interface_response_name}} {

        private final org.chromium.mojo.system.Core mCore;
        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
        private final long mRequestId;

        {{response_struct|name}}ProxyToResponder(
                org.chromium.mojo.system.Core core,
                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
                long requestId) {
            mCore = core;
            mMessageReceiver = messageReceiver;
            mRequestId = requestId;
        }

        @Override
        public void call({{declare_params(method.response_parameters, true)}}) {
            {{response_struct|name}} _response = new {{response_struct|name}}();
{%   for param in method.response_parameters %}
            _response.{{param|name}} = {{param|name}};
{%   endfor %}
            org.chromium.mojo.bindings.ServiceMessage _message =
                    _response.serializeWithHeader(
                            mCore,
                            new org.chromium.mojo.bindings.MessageHeader(
                                    {{method|method_ordinal_name}},
                                    {{flags_for_method(method, False)}},
                                    mRequestId));
            mMessageReceiver.accept(_message);
        }
    }
{%   endif %}
{% endfor %}

}
{% endmacro %}
