{%- import "cloudevents.jinja.include" as cloudEvents -%}
{%- import "util.jinja.include" as util -%}
{%- set data_module_name = data_project_name | strip_invalid_identifier_characters %}
// This code was generated by the xRegistry tool.
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.

import { EventGridPublisherClient, AzureKeyCredential } from '@azure/eventgrid';
import { DefaultAzureCredential } from '@azure/identity';
import { CloudEvent } from 'cloudevents';
import { v4 as uuidv4 } from 'uuid';

// Import data types (need to compile data project first: cd ../{{ data_project_name }} && npm install && npm run build)
// NOTE: In real usage, the data project should be a proper npm package dependency
import * as {{ data_module_name }} from '../../{{ data_project_name }}/dist/index.js';

{%- set messagegroups = root.messagegroups %}

{% for messagegroupid, messagegroup in messagegroups.items() -%}
{%- set groupname = messagegroupid | pascal -%}
{%- set class_name = (groupname | strip_namespace) + "EventGridProducer" %}

/**
 * Azure Event Grid producer for the `{{ messagegroupid }}` message group.
 */
export class {{ class_name }} {
    private client: EventGridPublisherClient<"CloudEvent">;
    
    /**
     * Constructor using access key authentication
     * @param endpoint The Event Grid topic endpoint URL
     * @param accessKey The access key for authentication
     */
    constructor(endpoint: string, accessKey: string);
    
    /**
     * Constructor using Azure AD authentication
     * @param endpoint The Event Grid topic endpoint URL
     */
    constructor(endpoint: string);
    
    constructor(endpoint: string, accessKey?: string) {
        if (accessKey) {
            this.client = new EventGridPublisherClient(
                endpoint,
                "CloudEvent",
                new AzureKeyCredential(accessKey)
            );
        } else {
            this.client = new EventGridPublisherClient(
                endpoint,
                "CloudEvent",
                new DefaultAzureCredential()
            );
        }
    }
    
    /**
     * Create a producer instance from an endpoint URL with key authentication
     * @param endpoint The Event Grid topic endpoint URL (including access key query parameter)
     * @returns A new {{ class_name }} instance
     */
    static createForEndpoint(endpoint: string): {{ class_name }} {
        const url = new URL(endpoint);
        const accessKey = url.searchParams.get('api-key');
        
        if (accessKey) {
            // Remove the access key from the URL
            url.searchParams.delete('api-key');
            return new {{ class_name }}(url.toString(), accessKey);
        } else {
            return new {{ class_name }}(endpoint);
        }
    }
    
    {% for messageid, message in messagegroup.messages.items() -%}
    {%- set messagename = messageid | pascal | strip_namespace %}
    {%- set isCloudEvent = cloudEvents.isCloudEvent(message) %}
    {%- set type_name = util.body_type(data_project_name, root, message) %}
    
    /**
     * Send the `{{ messagename }}` message
     {%- if message.description %}
     * {{ message.description }}
     {%- endif %}
     * @param data The message data object
     {%- for attrname, attribute in message.envelopemetadata.items() if attribute.type == "uritemplate" %}
     {%- for placeholder in attribute.value | regex_search('\\{([A-Za-z0-9_]+)\\}') %}
     * @param {{ placeholder }} Value for placeholder {{ placeholder }} in attribute {{ attrname }}
     {%- endfor %}
     {%- endfor %}
     {%- for attrname, attribute in message.envelopemetadata.items() if attribute.value is not defined and attrname not in ["time", "id", "datacontenttype", "dataschema"] %}
     * @param {{ attrname }} CloudEvent {{ attrname }} attribute{% if not attribute.required %} (optional){% endif %}
     {%- endfor %}
     */
    async send{{ messagename }}(
        data: {{ type_name }},
        {%- for attrname, attribute in message.envelopemetadata.items() if attribute.type == "uritemplate" %}
        {%- for placeholder in attribute.value | regex_search('\\{([A-Za-z0-9_]+)\\}') %}
        {{ placeholder }}: string,
        {%- endfor %}
        {%- endfor %}
        {%- for attrname, attribute in message.envelopemetadata.items() if attribute.value is not defined and attrname not in ["time", "id", "datacontenttype", "dataschema"] %}
        {{ attrname }}{% if not attribute.required %}?{% endif %}: string,
        {%- endfor %}
    ): Promise<void> {
        const cloudEvent: CloudEvent<{{ type_name }}> = new CloudEvent({
        {%- for attrname, attribute in message.envelopemetadata.items() %}
        {%- if attrname == "type" %}
            type: {% if attribute.value %}'{{ attribute.value }}'{% else %}{{ attrname }}{% endif %},
        {%- elif attrname == "source" %}
            source: {% if attribute.value %}{% if attribute.type == "uritemplate" %}`{{ attribute.value | regex_replace('\\{([A-Za-z0-9_]+)\\}', '${\\1}') }}`{% else %}'{{ attribute.value }}'{% endif %}{% else %}{{ attrname }} || '/producer'{% endif %},
        {%- elif attrname in ["id", "time"] %}
            {# id and time are auto-generated #}
        {%- elif attrname == "datacontenttype" %}
            {# handled separately #}
        {%- elif attrname == "dataschema" %}
            {# handled separately if needed #}
        {%- elif attribute.value %}
            {{ attrname }}: {% if attribute.type == "uritemplate" %}`{{ attribute.value | regex_replace('\\{([A-Za-z0-9_]+)\\}', '${\\1}') }}`{% else %}'{{ attribute.value }}'{% endif %},
        {%- else %}
            {% if not attribute.required %}...({{ attrname }} && { {{ attrname }} }),{% else %}{{ attrname }},{% endif %}
        {%- endif %}
        {%- endfor %}
            id: uuidv4(),
            data: data,
            datacontenttype: 'application/json'
        });
        
        await this.client.send([cloudEvent]);
    }
    
    /**
     * Send a batch of `{{ messagename }}` messages
     * @param dataArray Array of message data objects
     {%- for attrname, attribute in message.envelopemetadata.items() if attribute.type == "uritemplate" %}
     {%- for placeholder in attribute.value | regex_search('\\{([A-Za-z0-9_]+)\\}') %}
     * @param {{ placeholder }} Value for placeholder {{ placeholder }} in attribute {{ attrname }}
     {%- endfor %}
     {%- endfor %}
     {%- for attrname, attribute in message.envelopemetadata.items() if attribute.value is not defined and attrname not in ["time", "id", "datacontenttype", "dataschema"] %}
     * @param {{ attrname }} CloudEvent {{ attrname }} attribute{% if not attribute.required %} (optional){% endif %}
     {%- endfor %}
     */
    async send{{ messagename }}Batch(
        dataArray: {{ type_name }}[],
        {%- for attrname, attribute in message.envelopemetadata.items() if attribute.type == "uritemplate" %}
        {%- for placeholder in attribute.value | regex_search('\\{([A-Za-z0-9_]+)\\}') %}
        {{ placeholder }}: string,
        {%- endfor %}
        {%- endfor %}
        {%- for attrname, attribute in message.envelopemetadata.items() if attribute.value is not defined and attrname not in ["time", "id", "datacontenttype", "dataschema"] %}
        {{ attrname }}{% if not attribute.required %}?{% endif %}: string,
        {%- endfor %}
    ): Promise<void> {
        const cloudEvents: CloudEvent<{{ type_name }}>[] = dataArray.map(data => new CloudEvent({
        {%- for attrname, attribute in message.envelopemetadata.items() %}
        {%- if attrname == "type" %}
            type: {% if attribute.value %}'{{ attribute.value }}'{% else %}{{ attrname }}{% endif %},
        {%- elif attrname == "source" %}
            source: {% if attribute.value %}{% if attribute.type == "uritemplate" %}`{{ attribute.value | regex_replace('\\{([A-Za-z0-9_]+)\\}', '${\\1}') }}`{% else %}'{{ attribute.value }}'{% endif %}{% else %}{{ attrname }} || '/producer'{% endif %},
        {%- elif attrname in ["id", "time"] %}
            {# id and time are auto-generated #}
        {%- elif attrname == "datacontenttype" %}
            {# handled separately #}
        {%- elif attrname == "dataschema" %}
            {# handled separately if needed #}
        {%- elif attribute.value %}
            {{ attrname }}: {% if attribute.type == "uritemplate" %}`{{ attribute.value | regex_replace('\\{([A-Za-z0-9_]+)\\}', '${\\1}') }}`{% else %}'{{ attribute.value }}'{% endif %},
        {%- else %}
            {% if not attribute.required %}...({{ attrname }} && { {{ attrname }} }),{% else %}{{ attrname }},{% endif %}
        {%- endif %}
        {%- endfor %}
            id: uuidv4(),
            data: data,
            datacontenttype: 'application/json'
        }));
        
        await this.client.send(cloudEvents);
    }
    {% endfor %}
}
{% endfor %}
