{%- import "cloudevents.jinja.include" as cloudEvents -%}
{%- import "amqp.jinja.include" as amqp -%}
{%- import "mqtt.jinja.include" as mqtt -%}
{%- import "util.jinja.include" as util -%}
{{ util.CommonFileHeader() }}
{%- set messagegroups = root.messagegroups %}
{%- set uses_cloudevents_message = (root | exists("envelope","CloudEvents/1.0")) %}
{%- set uses_http_endpoint = (root | exists( "protocol", "http" )) %}
// this file was generated by xRegistry CLI
{%- if not uses_http_endpoint %}
{%- exit %}
{%- endif %}

using CloudNative.CloudEvents;
using CloudNative.CloudEvents.SystemTextJson;
using Azure;
using Azure.Core;
using Azure.Messaging.EventGrid;
using Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents;
using System.Threading.Tasks;

{% for messagegroupid, messagegroup in messagegroups.items() -%}
{%- set groupname = messagegroupid  | pascal -%}
namespace {{ project_name | pascal }}
{
    {%- set class_name = ( groupname | strip_namespace )+"ProducerClient" %}
    public partial class {{ class_name }}
    {
        private const string cePrefix = "cloudEvents_";
        private const string applicationOctetStream = "application/octet-stream";
        private readonly EventGridPublisherClient eventGridPublisherClient;
        public delegate byte[] Serialize<T>(T data, out ContentType contentType);
        private static CloudEventFormatter defaultFormatter = new JsonEventFormatter();

        public {{ class_name }}(EventGridPublisherClient eventGridPublisherClient)
        {
            this.eventGridPublisherClient = eventGridPublisherClient;
        }

        public EventGridPublisherClient EventGridPublisherClient
        {
            get 
            {
                return this.eventGridPublisherClient;
            }
        }

        {%- if root.endpoints -%} 
        {%- for endpointid, endpoint in root.endpoints.items() -%}
                {%- if endpoint.usage and "producer" in endpoint.usage -%}
        {%- set protocol = endpoint.protocol | lower -%}
        {%- if protocol == "http" -%}
        {%- set options = endpoint.protocoloptions -%}
        {%- set endpoints = endpoint.endpoints %}
        {%- macro createforbody(class_name, endpoints, options) -%}
            if ( endpointUrl == null )
            {
                {%- if endpoints %}
                endpointUrl = new Uri("{{ endpoints[0].uri }}");
                {%- else %}
                throw new ArgumentNullException(nameof(endpointUrl));
                {%- endif %}
            }
            var eventGridPublisherClient = new EventGridPublisherClient(endpointUrl, credential);
            return new {{ class_name }}(eventGridPublisherClient);
        {%- endmacro %}
        
        public static {{ class_name }} CreateFor{{ endpointid | pascal | strip_namespace }}(TokenCredential credential, Uri? endpointUrl = null, string? entityName = null) 
        {   
            {{ createforbody(class_name, endpoints, options) }}
        }

        public static {{ class_name }} CreateFor{{ endpointid | pascal | strip_namespace }}(AzureKeyCredential credential, Uri? endpointUrl = null, string? entityName = null) 
        {       
            {{ createforbody(class_name, endpoints, options) }}
        }

        public static {{ class_name }} CreateFor{{ endpointid | pascal | strip_namespace }}(AzureSasCredential credential, Uri? endpointUrl = null, string? entityName = null) 
        {       
            {{ createforbody(class_name, endpoints, options) }}
        }
        {%- endif -%}
        {%- endif -%}
        {%- endfor -%}
        {% endif %}

        {% for messageid, message in messagegroup.messages.items() -%}
        {%- set messagename = messageid | pascal %}
        {%- set isCloudEvent = not message.envelope or message.envelope.lower().startswith("cloudevents") -%}
        {%- if isCloudEvent %}
        {%- if message.description %}
        /// <summary>
        /// {{ message.description }}
        /// </summary>
        {%- endif %}
        public async Task Send{{ messagename | strip_namespace }}Async(
        {{ util.body_type(data_project_name, root, message) }} data
        {{- cloudEvents.DeclareUriTemplateArguments(message) -}},
        string contentType = System.Net.Mime.MediaTypeNames.Application.Json)
        {
            {{ cloudEvents.DeclareCloudNativeCloudEvent("cloudEvent", message) | indent(12) }}
            cloudEvent.Data = data;
            await eventGridPublisherClient.SendCloudNativeCloudEventAsync(cloudEvent);
        }
        {%- endif -%}
        {% endfor %}
    }
}
{% endfor -%}