{%- import 'util.jinja.include' as util -%}
{%- import 'cloudevents.jinja.include' as cloudEvents -%}
{%- import 'mqtt.jinja.include' as mqtt -%}
{{ util.CommonFileHeader() }}

{%- set messagegroups = root.messagegroups %}
{%- set package_name = project_name | lower | replace('-', '_') %}

{% for messagegroupid, messagegroup in messagegroups.items() -%}
{%- set groupname = messagegroupid | pascal -%}
{%- set group_package = (package_name ~ "." ~ messagegroupid) | lower | replace('-', '_') %}
package {{ group_package }};

import org.eclipse.paho.client.mqttv3.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

{%- for messageid, message in messagegroup.messages.items() %}
{%- set message_body_type = util.get_data_type(data_project_name, root, message) %}
{%- if '.' in message_body_type %}
import {{ message_body_type.rsplit('.', 1)[0] }}.*;
{%- endif %}
{%- endfor %}

{%- set producer_class = (groupname | strip_namespace) ~ 'Producer' %}

{#- Helper macro to get the default topic for a message -#}
{%- macro get_default_topic(message, messageid) -%}
{%- if message.protocoloptions and message.protocoloptions.properties and message.protocoloptions.properties.topic -%}
{{ message.protocoloptions.properties.topic.value }}
{%- elif message.binding and message.binding.mqtt and message.binding.mqtt.topic -%}
{{ message.binding.mqtt.topic }}
{%- elif message.metadata and message.metadata.attributes and message.metadata.attributes["topic-name"] -%}
{{ message.metadata.attributes["topic-name"].value }}
{%- else -%}
{{ messageid }}
{%- endif -%}
{%- endmacro -%}

/**
 * MQTT Producer for {{ messagegroupid }} message group.
 */
public class {{ producer_class }} implements AutoCloseable {
    private static final Logger logger = LogManager.getLogger({{ producer_class }}.class);
    
    private final MqttClient mqttClient;

    /**
     * Creates a new producer.
     * 
     * @param mqttClient The MQTT client to use for publishing
     */
    public {{ producer_class }}(MqttClient mqttClient) {
        this.mqttClient = mqttClient;
    }

    {%- for messageid, message in messagegroup.messages.items() %}
    {%- set messagename = messageid | pascal | strip_namespace %}
    {%- set message_body_type = util.get_data_type(data_project_name, root, message) %}
    {%- set default_topic = get_default_topic(message, messageid) %}

    /**
     * Send {{ messagename }} message to MQTT topic.
     * 
     * @param data The message data to send
     * @param topic Optional topic override. If null, uses default topic '{{ default_topic }}'.
     * @param qos Quality of Service (0, 1, or 2)
     * @throws MqttException if publishing fails
     {%- if message_body_type != "byte[]" %}
     * @throws Exception if serialization fails
     {%- endif %}
     */
    public void send{{ messagename }}({{ message_body_type }} data, String topic, int qos) throws {% if message_body_type != "byte[]" %}Exception{% else %}MqttException{% endif %} {
        String targetTopic = (topic != null && !topic.isEmpty()) ? topic : "{{ default_topic }}";
        
        {%- if message_body_type == "byte[]" %}
        byte[] payload = data;
        {%- else %}
        byte[] payload = data.toByteArray("application/json");
        {%- endif %}
        MqttMessage message = new MqttMessage(payload);
        message.setQos(qos);
        mqttClient.publish(targetTopic, message);
        logger.debug("Published {{ messagename }} to topic {}", targetTopic);
    }

    /**
     * Send {{ messagename }} message with QoS 1 to default topic.
     * 
     * @param data The message data to send
     * @throws MqttException if publishing fails
     {%- if message_body_type != "byte[]" %}
     * @throws Exception if serialization fails
     {%- endif %}
     */
    public void send{{ messagename }}({{ message_body_type }} data) throws {% if message_body_type != "byte[]" %}Exception{% else %}MqttException{% endif %} {
        send{{ messagename }}(data, null, 1);
    }

    /**
     * Send {{ messagename }} message with QoS 1.
     * 
     * @param data The message data to send
     * @param topic Optional topic override. If null, uses default topic '{{ default_topic }}'.
     * @throws MqttException if publishing fails
     {%- if message_body_type != "byte[]" %}
     * @throws Exception if serialization fails
     {%- endif %}
     */
    public void send{{ messagename }}({{ message_body_type }} data, String topic) throws {% if message_body_type != "byte[]" %}Exception{% else %}MqttException{% endif %} {
        send{{ messagename }}(data, topic, 1);
    }
    {%- endfor %}

    @Override
    public void close() {
        try {
            if (mqttClient != null && mqttClient.isConnected()) {
                mqttClient.disconnect();
                mqttClient.close();
            }
        } catch (MqttException e) {
            logger.error("Error closing producer", e);
        }
    }
}
{% endfor %}
