<#@ template language="C#" inherits="ActionTemplate" visibility="internal" linePragmas="false" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Core" #>
<#@ include file="Snippets/Index.tt" once="true" #>

/// <summary>
/// Adds a new message to the specified agent conversation
/// </summary>
internal sealed class <#= this.Name #>Executor(FormulaSession session, WorkflowAgentProvider agentProvider) : ActionExecutor(id: "<#= this.Id #>", session)
{
    // <inheritdoc />
    protected override async ValueTask<object?> ExecuteAsync(IWorkflowContext context, CancellationToken cancellationToken)
    {<# 
        EvaluateStringExpression(this.Model.ConversationId, "conversationId", isNullable: true); #>
        if (string.IsNullOrWhiteSpace(conversationId))
        {
            throw new DeclarativeActionException($"Conversation identifier must be defined: {this.Id}");
        }
        ChatMessage newMessage = new(ChatRole.<#= FormatEnum(this.Model.Role, RoleMap) #>, await this.GetContentAsync(context).ConfigureAwait(false)) { AdditionalProperties = this.GetMetadata() };
        newMessage = await agentProvider.CreateMessageAsync(conversationId, newMessage, cancellationToken).ConfigureAwait(false);<#
        AssignVariable(this.Message, "newMessage");
        #>
        return default;
    }

    private async ValueTask<IList<AIContent>> GetContentAsync(IWorkflowContext context)
    {
        List<AIContent> content = [];
        <#
        int index = 0;
        foreach (AddConversationMessageContent content in this.Model.Content)
        {
           ++index;
            EvaluateMessageTemplate(content.Value, $"contentValue{index}");
            AgentMessageContentType contentType = content.Type.Value;
            if (contentType == AgentMessageContentType.ImageUrl)
            {#>
        content.Add(UriContent(contentValue<#= index #>, "image/*"));<#
            }
            else if (contentType == AgentMessageContentType.ImageFile)
            {#>
        content.Add(new HostedFileContent(contentValue<#= index #>));<#
            }
            else
            {#>
        content.Add(new TextContent(contentValue<#= index #>));<#
            }
        }#>
        return content;
    }

    private AdditionalPropertiesDictionary? GetMetadata()
    {<# 
        EvaluateRecordExpression<object>(this.Model.Metadata, "metadata"); #>

        if (metadata is null)
        {
            return null;    
        }

        return new AdditionalPropertiesDictionary(metadata);
    }
}