{% macro cpp_type(type, interface=none, call=false) -%}
{% if type.is_variant -%}
std::variant<{{ type.cpp_type|join(', ') }}>
{%- else -%}
    {% if interface is not none and 'object_type' in type %}
        {{ interface + '::' + type.object_type }}
    {% else %}
        {% if call -%}{{'const '}}{%- endif %}
        {% if 'object_type' in type -%}
            {{ type.object_type }}
        {%- elif 'enum_type' in type -%}
            {{ type.enum_type }}
        {%- elif 'array_type' in type -%}
            std::vector<{{ type.array_type }}>
        {%- else -%}
            {{ type.cpp_type }}
        {%- endif %}
        {% if call -%}&{%- endif %}
    {%- endif %}
{%- endif %}
{%- endmacro %}

{% macro result_type(type, interface=none) -%}
{% if type -%}
{{ cpp_type(type) }}
{%- else -%}
void
{%- endif %}
{%- endmacro %}

{% macro var_to_any(var, name) -%}
{% if var.is_variant -%}
Everest::variant_to_json({{ name }})
{%- else -%}
{{ name }}
{%- endif %}
{%- endmacro %}

{% macro var_to_cpp(arg) -%}
{% if arg.is_variant -%}
Everest::json_to_variant<{{ arg.cpp_type|join(', ')}}>
{%- else -%}
static_cast<{{ arg.cpp_type }}>
{%- endif %}
{%- endmacro %}

{% macro call_cmd_signature(cmd, interface=none) -%}
{{ result_type(cmd.result, interface) }} call_{{ cmd.name }}(
{%- for arg in cmd.args -%}
{{ cpp_type(arg, none, true) }} {{ arg.name }}{{ ', ' if not loop.last }}
{%- endfor -%}
)
{%- endmacro %}

{% macro handle_cmd_signature(cmd, class_name=None, interface=none) -%}
{% if not class_name %}virtual {% endif -%}
{{ result_type(cmd.result, interface) }} {% if class_name %}{{ class_name }}::{% endif -%}
handle_{{ cmd.name }}(
{%- for arg in cmd.args -%}
{{ cpp_type(arg) }}& {{ arg.name }}{{ ', ' if not loop.last }}
{%- endfor -%}
)
{%- endmacro %}

{% macro publish_var_signature(var) %}
void publish_{{ var.name }}({% if var.json_type != 'null' %}{{ cpp_type(var) }} value{% endif %}) {
        _ev->publish(_name, "{{ var.name }}", {% if var.json_type != 'null' %}{{ var_to_any(var, 'value')}}{% else %}nullptr{% endif %});
}
{% endmacro %}

{% macro list_json_types(json_type) -%}
{% if json_type is iterable and json_type is not string -%}
{
{%- for type in json_type -%}
"{{ type }}"{{ ', ' if not loop.last}}
{%- endfor -%}
}
{%- else -%}
{"{{ json_type }}"}
{%- endif %}
{%- endmacro %}

{% macro insert_block(block, indent=0) %}
{{ block.tag }}
{{ " "*indent if block.first_use }}{{ block.content }}
{{ " "*indent }}{{ block.tag }}
{%- endmacro %}

{% macro print_spdx_line(license, year_tag=None) %}
// SPDX-License-Identifier: {{ license }}
// Copyright{% if year_tag %} {{ year_tag }}{% endif %} Pionix GmbH and Contributors to EVerest
{%- endmacro %}

{% macro print_license_header(license) %}
{{ license }}
{%- endmacro %}

{% macro print_template_info(version, title='DO NOT EDIT!', comment_sep='//') %}
{{ comment_sep }}
{{ comment_sep }} AUTO GENERATED - {{ title|upper }}
{{ comment_sep }} template version {{ version }}
{{ comment_sep }}
{%- endmacro %}

{% macro string_to_enum(enum_type) %}
{% if '::' not in enum_type %}
string_to_{{ enum_type | snake_case -}}
{% else %}
{{ enum_type[:enum_type.rfind('::')] }}::string_to_{{ enum_type[(enum_type.rfind('::')+2):] | snake_case -}}
{% endif %}
{%- endmacro %}

{% macro enum_to_string(enum_type) %}
{% if '::' not in enum_type %}
{{ enum_type | snake_case }}_to_string
{%- else %}
{{ enum_type[:enum_type.rfind('::')] }}::{{ enum_type[(enum_type.rfind('::')+2):] | snake_case }}_to_string
{%- endif %}
{%- endmacro %}

{% macro enum_to_string_view(enum_type) %}
{% if '::' not in enum_type %}
{{ enum_type | snake_case }}_to_string_view
{%- else %}
{{ enum_type[:enum_type.rfind('::')] }}::{{ enum_type[(enum_type.rfind('::')+2):] | snake_case }}_to_string_view
{%- endif %}
{%- endmacro %}
