// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.communication.chat.implementation;

import com.azure.communication.chat.implementation.models.AddChatParticipantsOptions;
import com.azure.communication.chat.implementation.models.AddChatParticipantsResult;
import com.azure.communication.chat.implementation.models.ChatMessage;
import com.azure.communication.chat.implementation.models.ChatMessageReadReceipt;
import com.azure.communication.chat.implementation.models.ChatMessageReadReceiptsCollection;
import com.azure.communication.chat.implementation.models.ChatMessagesCollection;
import com.azure.communication.chat.implementation.models.ChatParticipant;
import com.azure.communication.chat.implementation.models.ChatParticipantsCollection;
import com.azure.communication.chat.implementation.models.ChatThreadProperties;
import com.azure.communication.chat.implementation.models.CommunicationErrorResponseException;
import com.azure.communication.chat.implementation.models.CommunicationIdentifierModel;
import com.azure.communication.chat.implementation.models.SendReadReceiptRequest;
import com.azure.communication.chat.models.SendChatMessageOptions;
import com.azure.communication.chat.models.SendChatMessageResult;
import com.azure.communication.chat.models.TypingNotificationOptions;
import com.azure.communication.chat.models.UpdateChatMessageOptions;
import com.azure.communication.chat.models.UpdateChatThreadOptions;
import com.azure.core.annotation.BodyParam;
import com.azure.core.annotation.Delete;
import com.azure.core.annotation.ExpectedResponses;
import com.azure.core.annotation.Get;
import com.azure.core.annotation.HeaderParam;
import com.azure.core.annotation.Host;
import com.azure.core.annotation.HostParam;
import com.azure.core.annotation.Patch;
import com.azure.core.annotation.PathParam;
import com.azure.core.annotation.Post;
import com.azure.core.annotation.QueryParam;
import com.azure.core.annotation.ReturnType;
import com.azure.core.annotation.ServiceInterface;
import com.azure.core.annotation.ServiceMethod;
import com.azure.core.annotation.UnexpectedResponseExceptionType;
import com.azure.core.http.rest.PagedFlux;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.http.rest.PagedResponse;
import com.azure.core.http.rest.PagedResponseBase;
import com.azure.core.http.rest.Response;
import com.azure.core.http.rest.RestProxy;
import com.azure.core.util.Context;
import com.azure.core.util.FluxUtil;
import java.time.OffsetDateTime;
import reactor.core.publisher.Mono;

/** An instance of this class provides access to all the operations defined in ChatThreads. */
public final class ChatThreadsImpl {
    /** The proxy service used to perform REST calls. */
    private final ChatThreadsService service;

    /** The service client containing this operation class. */
    private final AzureCommunicationChatServiceImpl client;

    /**
     * Initializes an instance of ChatThreadsImpl.
     *
     * @param client the instance of the service client containing this operation class.
     */
    ChatThreadsImpl(AzureCommunicationChatServiceImpl client) {
        this.service =
                RestProxy.create(ChatThreadsService.class, client.getHttpPipeline(), client.getSerializerAdapter());
        this.client = client;
    }

    /**
     * The interface defining all the services for AzureCommunicationChatServiceChatThreads to be used by the proxy
     * service to perform REST calls.
     */
    @Host("{endpoint}")
    @ServiceInterface(name = "AzureCommunicationCh")
    public interface ChatThreadsService {
        @Get("/chat/threads/{chatThreadId}/readReceipts")
        @ExpectedResponses({200})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<ChatMessageReadReceiptsCollection>> listChatReadReceipts(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @QueryParam("maxPageSize") Integer maxPageSize,
                @QueryParam("skip") Integer skip,
                @QueryParam("api-version") String apiVersion,
                @HeaderParam("Accept") String accept,
                Context context);

        @Post("/chat/threads/{chatThreadId}/readReceipts")
        @ExpectedResponses({200})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<Void>> sendChatReadReceipt(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @QueryParam("api-version") String apiVersion,
                @BodyParam("application/json") SendReadReceiptRequest sendReadReceiptRequest,
                @HeaderParam("Accept") String accept,
                Context context);

        @Post("/chat/threads/{chatThreadId}/messages")
        @ExpectedResponses({201})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<SendChatMessageResult>> sendChatMessage(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @QueryParam("api-version") String apiVersion,
                @BodyParam("application/json") SendChatMessageOptions sendChatMessageRequest,
                @HeaderParam("Accept") String accept,
                Context context);

        @Get("/chat/threads/{chatThreadId}/messages")
        @ExpectedResponses({200})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<ChatMessagesCollection>> listChatMessages(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @QueryParam("maxPageSize") Integer maxPageSize,
                @QueryParam("startTime") OffsetDateTime startTime,
                @QueryParam("api-version") String apiVersion,
                @HeaderParam("Accept") String accept,
                Context context);

        @Get("/chat/threads/{chatThreadId}/messages/{chatMessageId}")
        @ExpectedResponses({200})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<ChatMessage>> getChatMessage(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @PathParam("chatMessageId") String chatMessageId,
                @QueryParam("api-version") String apiVersion,
                @HeaderParam("Accept") String accept,
                Context context);

        @Patch("/chat/threads/{chatThreadId}/messages/{chatMessageId}")
        @ExpectedResponses({204})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<Void>> updateChatMessage(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @PathParam("chatMessageId") String chatMessageId,
                @QueryParam("api-version") String apiVersion,
                @BodyParam("application/merge-patch+json") UpdateChatMessageOptions updateChatMessageRequest,
                @HeaderParam("Accept") String accept,
                Context context);

        @Delete("/chat/threads/{chatThreadId}/messages/{chatMessageId}")
        @ExpectedResponses({204})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<Void>> deleteChatMessage(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @PathParam("chatMessageId") String chatMessageId,
                @QueryParam("api-version") String apiVersion,
                @HeaderParam("Accept") String accept,
                Context context);

        @Get("/chat/threads/{chatThreadId}/participants")
        @ExpectedResponses({200})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<ChatParticipantsCollection>> listChatParticipants(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @QueryParam("maxPageSize") Integer maxPageSize,
                @QueryParam("skip") Integer skip,
                @QueryParam("api-version") String apiVersion,
                @HeaderParam("Accept") String accept,
                Context context);

        @Post("/chat/threads/{chatThreadId}/participants/:remove")
        @ExpectedResponses({204})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<Void>> removeChatParticipant(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @QueryParam("api-version") String apiVersion,
                @BodyParam("application/json") CommunicationIdentifierModel participantCommunicationIdentifier,
                @HeaderParam("Accept") String accept,
                Context context);

        @Post("/chat/threads/{chatThreadId}/participants/:add")
        @ExpectedResponses({201})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<AddChatParticipantsResult>> addChatParticipants(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @QueryParam("api-version") String apiVersion,
                @BodyParam("application/json") AddChatParticipantsOptions addChatParticipantsRequest,
                @HeaderParam("Accept") String accept,
                Context context);

        @Patch("/chat/threads/{chatThreadId}")
        @ExpectedResponses({204})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<Void>> updateChatThreadProperties(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @QueryParam("api-version") String apiVersion,
                @BodyParam("application/merge-patch+json") UpdateChatThreadOptions updateChatThreadRequest,
                @HeaderParam("Accept") String accept,
                Context context);

        @Get("/chat/threads/{chatThreadId}")
        @ExpectedResponses({200})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<ChatThreadProperties>> getChatThreadProperties(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @QueryParam("api-version") String apiVersion,
                @HeaderParam("Accept") String accept,
                Context context);

        @Post("/chat/threads/{chatThreadId}/typing")
        @ExpectedResponses({200})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<Void>> sendTypingNotification(
                @HostParam("endpoint") String endpoint,
                @PathParam("chatThreadId") String chatThreadId,
                @QueryParam("api-version") String apiVersion,
                @BodyParam("application/json") TypingNotificationOptions sendTypingNotificationRequest,
                @HeaderParam("Accept") String accept,
                Context context);

        @Get("{nextLink}")
        @ExpectedResponses({200})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<ChatMessageReadReceiptsCollection>> listChatReadReceiptsNext(
                @PathParam(value = "nextLink", encoded = true) String nextLink,
                @HostParam("endpoint") String endpoint,
                @HeaderParam("Accept") String accept,
                Context context);

        @Get("{nextLink}")
        @ExpectedResponses({200})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<ChatMessagesCollection>> listChatMessagesNext(
                @PathParam(value = "nextLink", encoded = true) String nextLink,
                @HostParam("endpoint") String endpoint,
                @HeaderParam("Accept") String accept,
                Context context);

        @Get("{nextLink}")
        @ExpectedResponses({200})
        @UnexpectedResponseExceptionType(CommunicationErrorResponseException.class)
        Mono<Response<ChatParticipantsCollection>> listChatParticipantsNext(
                @PathParam(value = "nextLink", encoded = true) String nextLink,
                @HostParam("endpoint") String endpoint,
                @HeaderParam("Accept") String accept,
                Context context);
    }

    /**
     * Gets chat message read receipts for a thread.
     *
     * @param chatThreadId Thread id to get the chat message read receipts for.
     * @param maxPageSize The maximum number of chat message read receipts to be returned per page.
     * @param skip Skips chat message read receipts up to a specified position in response.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return chat message read receipts for a thread.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatMessageReadReceipt>> listChatReadReceiptsSinglePageAsync(
            String chatThreadId, Integer maxPageSize, Integer skip) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                        context ->
                                service.listChatReadReceipts(
                                        this.client.getEndpoint(),
                                        chatThreadId,
                                        maxPageSize,
                                        skip,
                                        this.client.getApiVersion(),
                                        accept,
                                        context))
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Gets chat message read receipts for a thread.
     *
     * @param chatThreadId Thread id to get the chat message read receipts for.
     * @param maxPageSize The maximum number of chat message read receipts to be returned per page.
     * @param skip Skips chat message read receipts up to a specified position in response.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return chat message read receipts for a thread.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatMessageReadReceipt>> listChatReadReceiptsSinglePageAsync(
            String chatThreadId, Integer maxPageSize, Integer skip, Context context) {
        final String accept = "application/json";
        return service.listChatReadReceipts(
                        this.client.getEndpoint(),
                        chatThreadId,
                        maxPageSize,
                        skip,
                        this.client.getApiVersion(),
                        accept,
                        context)
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Gets chat message read receipts for a thread.
     *
     * @param chatThreadId Thread id to get the chat message read receipts for.
     * @param maxPageSize The maximum number of chat message read receipts to be returned per page.
     * @param skip Skips chat message read receipts up to a specified position in response.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return chat message read receipts for a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<ChatMessageReadReceipt> listChatReadReceiptsAsync(
            String chatThreadId, Integer maxPageSize, Integer skip) {
        return new PagedFlux<>(
                () -> listChatReadReceiptsSinglePageAsync(chatThreadId, maxPageSize, skip),
                nextLink -> listChatReadReceiptsNextSinglePageAsync(nextLink));
    }

    /**
     * Gets chat message read receipts for a thread.
     *
     * @param chatThreadId Thread id to get the chat message read receipts for.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return chat message read receipts for a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<ChatMessageReadReceipt> listChatReadReceiptsAsync(String chatThreadId) {
        final Integer maxPageSize = null;
        final Integer skip = null;
        return new PagedFlux<>(
                () -> listChatReadReceiptsSinglePageAsync(chatThreadId, maxPageSize, skip),
                nextLink -> listChatReadReceiptsNextSinglePageAsync(nextLink));
    }

    /**
     * Gets chat message read receipts for a thread.
     *
     * @param chatThreadId Thread id to get the chat message read receipts for.
     * @param maxPageSize The maximum number of chat message read receipts to be returned per page.
     * @param skip Skips chat message read receipts up to a specified position in response.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return chat message read receipts for a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<ChatMessageReadReceipt> listChatReadReceiptsAsync(
            String chatThreadId, Integer maxPageSize, Integer skip, Context context) {
        return new PagedFlux<>(
                () -> listChatReadReceiptsSinglePageAsync(chatThreadId, maxPageSize, skip, context),
                nextLink -> listChatReadReceiptsNextSinglePageAsync(nextLink, context));
    }

    /**
     * Gets chat message read receipts for a thread.
     *
     * @param chatThreadId Thread id to get the chat message read receipts for.
     * @param maxPageSize The maximum number of chat message read receipts to be returned per page.
     * @param skip Skips chat message read receipts up to a specified position in response.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return chat message read receipts for a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedIterable<ChatMessageReadReceipt> listChatReadReceipts(
            String chatThreadId, Integer maxPageSize, Integer skip) {
        return new PagedIterable<>(listChatReadReceiptsAsync(chatThreadId, maxPageSize, skip));
    }

    /**
     * Gets chat message read receipts for a thread.
     *
     * @param chatThreadId Thread id to get the chat message read receipts for.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return chat message read receipts for a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedIterable<ChatMessageReadReceipt> listChatReadReceipts(String chatThreadId) {
        final Integer maxPageSize = null;
        final Integer skip = null;
        return new PagedIterable<>(listChatReadReceiptsAsync(chatThreadId, maxPageSize, skip));
    }

    /**
     * Gets chat message read receipts for a thread.
     *
     * @param chatThreadId Thread id to get the chat message read receipts for.
     * @param maxPageSize The maximum number of chat message read receipts to be returned per page.
     * @param skip Skips chat message read receipts up to a specified position in response.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return chat message read receipts for a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedIterable<ChatMessageReadReceipt> listChatReadReceipts(
            String chatThreadId, Integer maxPageSize, Integer skip, Context context) {
        return new PagedIterable<>(listChatReadReceiptsAsync(chatThreadId, maxPageSize, skip, context));
    }

    /**
     * Sends a read receipt event to a thread, on behalf of a user.
     *
     * @param chatThreadId Thread id to send the read receipt event to.
     * @param sendReadReceiptRequest Read receipt details.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> sendChatReadReceiptWithResponseAsync(
            String chatThreadId, SendReadReceiptRequest sendReadReceiptRequest) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                context ->
                        service.sendChatReadReceipt(
                                this.client.getEndpoint(),
                                chatThreadId,
                                this.client.getApiVersion(),
                                sendReadReceiptRequest,
                                accept,
                                context));
    }

    /**
     * Sends a read receipt event to a thread, on behalf of a user.
     *
     * @param chatThreadId Thread id to send the read receipt event to.
     * @param sendReadReceiptRequest Read receipt details.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> sendChatReadReceiptWithResponseAsync(
            String chatThreadId, SendReadReceiptRequest sendReadReceiptRequest, Context context) {
        final String accept = "application/json";
        return service.sendChatReadReceipt(
                this.client.getEndpoint(),
                chatThreadId,
                this.client.getApiVersion(),
                sendReadReceiptRequest,
                accept,
                context);
    }

    /**
     * Sends a read receipt event to a thread, on behalf of a user.
     *
     * @param chatThreadId Thread id to send the read receipt event to.
     * @param sendReadReceiptRequest Read receipt details.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> sendChatReadReceiptAsync(String chatThreadId, SendReadReceiptRequest sendReadReceiptRequest) {
        return sendChatReadReceiptWithResponseAsync(chatThreadId, sendReadReceiptRequest)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Sends a read receipt event to a thread, on behalf of a user.
     *
     * @param chatThreadId Thread id to send the read receipt event to.
     * @param sendReadReceiptRequest Read receipt details.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> sendChatReadReceiptAsync(
            String chatThreadId, SendReadReceiptRequest sendReadReceiptRequest, Context context) {
        return sendChatReadReceiptWithResponseAsync(chatThreadId, sendReadReceiptRequest, context)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Sends a read receipt event to a thread, on behalf of a user.
     *
     * @param chatThreadId Thread id to send the read receipt event to.
     * @param sendReadReceiptRequest Read receipt details.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public void sendChatReadReceipt(String chatThreadId, SendReadReceiptRequest sendReadReceiptRequest) {
        sendChatReadReceiptAsync(chatThreadId, sendReadReceiptRequest).block();
    }

    /**
     * Sends a read receipt event to a thread, on behalf of a user.
     *
     * @param chatThreadId Thread id to send the read receipt event to.
     * @param sendReadReceiptRequest Read receipt details.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the response.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Response<Void> sendChatReadReceiptWithResponse(
            String chatThreadId, SendReadReceiptRequest sendReadReceiptRequest, Context context) {
        return sendChatReadReceiptWithResponseAsync(chatThreadId, sendReadReceiptRequest, context).block();
    }

    /**
     * Sends a message to a thread.
     *
     * @param chatThreadId The thread id to send the message to.
     * @param sendChatMessageRequest Details of the message to send.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the send message operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<SendChatMessageResult>> sendChatMessageWithResponseAsync(
            String chatThreadId, SendChatMessageOptions sendChatMessageRequest) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                context ->
                        service.sendChatMessage(
                                this.client.getEndpoint(),
                                chatThreadId,
                                this.client.getApiVersion(),
                                sendChatMessageRequest,
                                accept,
                                context));
    }

    /**
     * Sends a message to a thread.
     *
     * @param chatThreadId The thread id to send the message to.
     * @param sendChatMessageRequest Details of the message to send.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the send message operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<SendChatMessageResult>> sendChatMessageWithResponseAsync(
            String chatThreadId, SendChatMessageOptions sendChatMessageRequest, Context context) {
        final String accept = "application/json";
        return service.sendChatMessage(
                this.client.getEndpoint(),
                chatThreadId,
                this.client.getApiVersion(),
                sendChatMessageRequest,
                accept,
                context);
    }

    /**
     * Sends a message to a thread.
     *
     * @param chatThreadId The thread id to send the message to.
     * @param sendChatMessageRequest Details of the message to send.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the send message operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<SendChatMessageResult> sendChatMessageAsync(
            String chatThreadId, SendChatMessageOptions sendChatMessageRequest) {
        return sendChatMessageWithResponseAsync(chatThreadId, sendChatMessageRequest)
                .flatMap(
                        (Response<SendChatMessageResult> res) -> {
                            if (res.getValue() != null) {
                                return Mono.just(res.getValue());
                            } else {
                                return Mono.empty();
                            }
                        });
    }

    /**
     * Sends a message to a thread.
     *
     * @param chatThreadId The thread id to send the message to.
     * @param sendChatMessageRequest Details of the message to send.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the send message operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<SendChatMessageResult> sendChatMessageAsync(
            String chatThreadId, SendChatMessageOptions sendChatMessageRequest, Context context) {
        return sendChatMessageWithResponseAsync(chatThreadId, sendChatMessageRequest, context)
                .flatMap(
                        (Response<SendChatMessageResult> res) -> {
                            if (res.getValue() != null) {
                                return Mono.just(res.getValue());
                            } else {
                                return Mono.empty();
                            }
                        });
    }

    /**
     * Sends a message to a thread.
     *
     * @param chatThreadId The thread id to send the message to.
     * @param sendChatMessageRequest Details of the message to send.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the send message operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public SendChatMessageResult sendChatMessage(String chatThreadId, SendChatMessageOptions sendChatMessageRequest) {
        return sendChatMessageAsync(chatThreadId, sendChatMessageRequest).block();
    }

    /**
     * Sends a message to a thread.
     *
     * @param chatThreadId The thread id to send the message to.
     * @param sendChatMessageRequest Details of the message to send.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the send message operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Response<SendChatMessageResult> sendChatMessageWithResponse(
            String chatThreadId, SendChatMessageOptions sendChatMessageRequest, Context context) {
        return sendChatMessageWithResponseAsync(chatThreadId, sendChatMessageRequest, context).block();
    }

    /**
     * Gets a list of messages from a thread.
     *
     * @param chatThreadId The thread id of the message.
     * @param maxPageSize The maximum number of messages to be returned per page.
     * @param startTime The earliest point in time to get messages up to. The timestamp should be in RFC3339 format:
     *     `yyyy-MM-ddTHH:mm:ssZ`.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a list of messages from a thread.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatMessage>> listChatMessagesSinglePageAsync(
            String chatThreadId, Integer maxPageSize, OffsetDateTime startTime) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                        context ->
                                service.listChatMessages(
                                        this.client.getEndpoint(),
                                        chatThreadId,
                                        maxPageSize,
                                        startTime,
                                        this.client.getApiVersion(),
                                        accept,
                                        context))
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Gets a list of messages from a thread.
     *
     * @param chatThreadId The thread id of the message.
     * @param maxPageSize The maximum number of messages to be returned per page.
     * @param startTime The earliest point in time to get messages up to. The timestamp should be in RFC3339 format:
     *     `yyyy-MM-ddTHH:mm:ssZ`.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a list of messages from a thread.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatMessage>> listChatMessagesSinglePageAsync(
            String chatThreadId, Integer maxPageSize, OffsetDateTime startTime, Context context) {
        final String accept = "application/json";
        return service.listChatMessages(
                        this.client.getEndpoint(),
                        chatThreadId,
                        maxPageSize,
                        startTime,
                        this.client.getApiVersion(),
                        accept,
                        context)
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Gets a list of messages from a thread.
     *
     * @param chatThreadId The thread id of the message.
     * @param maxPageSize The maximum number of messages to be returned per page.
     * @param startTime The earliest point in time to get messages up to. The timestamp should be in RFC3339 format:
     *     `yyyy-MM-ddTHH:mm:ssZ`.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a list of messages from a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<ChatMessage> listChatMessagesAsync(
            String chatThreadId, Integer maxPageSize, OffsetDateTime startTime) {
        return new PagedFlux<>(
                () -> listChatMessagesSinglePageAsync(chatThreadId, maxPageSize, startTime),
                nextLink -> listChatMessagesNextSinglePageAsync(nextLink));
    }

    /**
     * Gets a list of messages from a thread.
     *
     * @param chatThreadId The thread id of the message.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a list of messages from a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<ChatMessage> listChatMessagesAsync(String chatThreadId) {
        final Integer maxPageSize = null;
        final OffsetDateTime startTime = null;
        return new PagedFlux<>(
                () -> listChatMessagesSinglePageAsync(chatThreadId, maxPageSize, startTime),
                nextLink -> listChatMessagesNextSinglePageAsync(nextLink));
    }

    /**
     * Gets a list of messages from a thread.
     *
     * @param chatThreadId The thread id of the message.
     * @param maxPageSize The maximum number of messages to be returned per page.
     * @param startTime The earliest point in time to get messages up to. The timestamp should be in RFC3339 format:
     *     `yyyy-MM-ddTHH:mm:ssZ`.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a list of messages from a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<ChatMessage> listChatMessagesAsync(
            String chatThreadId, Integer maxPageSize, OffsetDateTime startTime, Context context) {
        return new PagedFlux<>(
                () -> listChatMessagesSinglePageAsync(chatThreadId, maxPageSize, startTime, context),
                nextLink -> listChatMessagesNextSinglePageAsync(nextLink, context));
    }

    /**
     * Gets a list of messages from a thread.
     *
     * @param chatThreadId The thread id of the message.
     * @param maxPageSize The maximum number of messages to be returned per page.
     * @param startTime The earliest point in time to get messages up to. The timestamp should be in RFC3339 format:
     *     `yyyy-MM-ddTHH:mm:ssZ`.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a list of messages from a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedIterable<ChatMessage> listChatMessages(
            String chatThreadId, Integer maxPageSize, OffsetDateTime startTime) {
        return new PagedIterable<>(listChatMessagesAsync(chatThreadId, maxPageSize, startTime));
    }

    /**
     * Gets a list of messages from a thread.
     *
     * @param chatThreadId The thread id of the message.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a list of messages from a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedIterable<ChatMessage> listChatMessages(String chatThreadId) {
        final Integer maxPageSize = null;
        final OffsetDateTime startTime = null;
        return new PagedIterable<>(listChatMessagesAsync(chatThreadId, maxPageSize, startTime));
    }

    /**
     * Gets a list of messages from a thread.
     *
     * @param chatThreadId The thread id of the message.
     * @param maxPageSize The maximum number of messages to be returned per page.
     * @param startTime The earliest point in time to get messages up to. The timestamp should be in RFC3339 format:
     *     `yyyy-MM-ddTHH:mm:ssZ`.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a list of messages from a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedIterable<ChatMessage> listChatMessages(
            String chatThreadId, Integer maxPageSize, OffsetDateTime startTime, Context context) {
        return new PagedIterable<>(listChatMessagesAsync(chatThreadId, maxPageSize, startTime, context));
    }

    /**
     * Gets a message by id.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a message by id.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<ChatMessage>> getChatMessageWithResponseAsync(String chatThreadId, String chatMessageId) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                context ->
                        service.getChatMessage(
                                this.client.getEndpoint(),
                                chatThreadId,
                                chatMessageId,
                                this.client.getApiVersion(),
                                accept,
                                context));
    }

    /**
     * Gets a message by id.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a message by id.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<ChatMessage>> getChatMessageWithResponseAsync(
            String chatThreadId, String chatMessageId, Context context) {
        final String accept = "application/json";
        return service.getChatMessage(
                this.client.getEndpoint(), chatThreadId, chatMessageId, this.client.getApiVersion(), accept, context);
    }

    /**
     * Gets a message by id.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a message by id.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<ChatMessage> getChatMessageAsync(String chatThreadId, String chatMessageId) {
        return getChatMessageWithResponseAsync(chatThreadId, chatMessageId)
                .flatMap(
                        (Response<ChatMessage> res) -> {
                            if (res.getValue() != null) {
                                return Mono.just(res.getValue());
                            } else {
                                return Mono.empty();
                            }
                        });
    }

    /**
     * Gets a message by id.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a message by id.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<ChatMessage> getChatMessageAsync(String chatThreadId, String chatMessageId, Context context) {
        return getChatMessageWithResponseAsync(chatThreadId, chatMessageId, context)
                .flatMap(
                        (Response<ChatMessage> res) -> {
                            if (res.getValue() != null) {
                                return Mono.just(res.getValue());
                            } else {
                                return Mono.empty();
                            }
                        });
    }

    /**
     * Gets a message by id.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a message by id.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public ChatMessage getChatMessage(String chatThreadId, String chatMessageId) {
        return getChatMessageAsync(chatThreadId, chatMessageId).block();
    }

    /**
     * Gets a message by id.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a message by id.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Response<ChatMessage> getChatMessageWithResponse(
            String chatThreadId, String chatMessageId, Context context) {
        return getChatMessageWithResponseAsync(chatThreadId, chatMessageId, context).block();
    }

    /**
     * Updates a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param updateChatMessageRequest Details of the request to update the message.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> updateChatMessageWithResponseAsync(
            String chatThreadId, String chatMessageId, UpdateChatMessageOptions updateChatMessageRequest) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                context ->
                        service.updateChatMessage(
                                this.client.getEndpoint(),
                                chatThreadId,
                                chatMessageId,
                                this.client.getApiVersion(),
                                updateChatMessageRequest,
                                accept,
                                context));
    }

    /**
     * Updates a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param updateChatMessageRequest Details of the request to update the message.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> updateChatMessageWithResponseAsync(
            String chatThreadId,
            String chatMessageId,
            UpdateChatMessageOptions updateChatMessageRequest,
            Context context) {
        final String accept = "application/json";
        return service.updateChatMessage(
                this.client.getEndpoint(),
                chatThreadId,
                chatMessageId,
                this.client.getApiVersion(),
                updateChatMessageRequest,
                accept,
                context);
    }

    /**
     * Updates a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param updateChatMessageRequest Details of the request to update the message.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> updateChatMessageAsync(
            String chatThreadId, String chatMessageId, UpdateChatMessageOptions updateChatMessageRequest) {
        return updateChatMessageWithResponseAsync(chatThreadId, chatMessageId, updateChatMessageRequest)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Updates a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param updateChatMessageRequest Details of the request to update the message.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> updateChatMessageAsync(
            String chatThreadId,
            String chatMessageId,
            UpdateChatMessageOptions updateChatMessageRequest,
            Context context) {
        return updateChatMessageWithResponseAsync(chatThreadId, chatMessageId, updateChatMessageRequest, context)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Updates a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param updateChatMessageRequest Details of the request to update the message.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public void updateChatMessage(
            String chatThreadId, String chatMessageId, UpdateChatMessageOptions updateChatMessageRequest) {
        updateChatMessageAsync(chatThreadId, chatMessageId, updateChatMessageRequest).block();
    }

    /**
     * Updates a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param updateChatMessageRequest Details of the request to update the message.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the response.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Response<Void> updateChatMessageWithResponse(
            String chatThreadId,
            String chatMessageId,
            UpdateChatMessageOptions updateChatMessageRequest,
            Context context) {
        return updateChatMessageWithResponseAsync(chatThreadId, chatMessageId, updateChatMessageRequest, context)
                .block();
    }

    /**
     * Deletes a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> deleteChatMessageWithResponseAsync(String chatThreadId, String chatMessageId) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                context ->
                        service.deleteChatMessage(
                                this.client.getEndpoint(),
                                chatThreadId,
                                chatMessageId,
                                this.client.getApiVersion(),
                                accept,
                                context));
    }

    /**
     * Deletes a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> deleteChatMessageWithResponseAsync(
            String chatThreadId, String chatMessageId, Context context) {
        final String accept = "application/json";
        return service.deleteChatMessage(
                this.client.getEndpoint(), chatThreadId, chatMessageId, this.client.getApiVersion(), accept, context);
    }

    /**
     * Deletes a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> deleteChatMessageAsync(String chatThreadId, String chatMessageId) {
        return deleteChatMessageWithResponseAsync(chatThreadId, chatMessageId)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Deletes a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> deleteChatMessageAsync(String chatThreadId, String chatMessageId, Context context) {
        return deleteChatMessageWithResponseAsync(chatThreadId, chatMessageId, context)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Deletes a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public void deleteChatMessage(String chatThreadId, String chatMessageId) {
        deleteChatMessageAsync(chatThreadId, chatMessageId).block();
    }

    /**
     * Deletes a message.
     *
     * @param chatThreadId The thread id to which the message was sent.
     * @param chatMessageId The message id.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the response.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Response<Void> deleteChatMessageWithResponse(String chatThreadId, String chatMessageId, Context context) {
        return deleteChatMessageWithResponseAsync(chatThreadId, chatMessageId, context).block();
    }

    /**
     * Gets the participants of a thread.
     *
     * @param chatThreadId Thread id to get participants for.
     * @param maxPageSize The maximum number of participants to be returned per page.
     * @param skip Skips participants up to a specified position in response.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the participants of a thread.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatParticipant>> listChatParticipantsSinglePageAsync(
            String chatThreadId, Integer maxPageSize, Integer skip) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                        context ->
                                service.listChatParticipants(
                                        this.client.getEndpoint(),
                                        chatThreadId,
                                        maxPageSize,
                                        skip,
                                        this.client.getApiVersion(),
                                        accept,
                                        context))
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Gets the participants of a thread.
     *
     * @param chatThreadId Thread id to get participants for.
     * @param maxPageSize The maximum number of participants to be returned per page.
     * @param skip Skips participants up to a specified position in response.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the participants of a thread.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatParticipant>> listChatParticipantsSinglePageAsync(
            String chatThreadId, Integer maxPageSize, Integer skip, Context context) {
        final String accept = "application/json";
        return service.listChatParticipants(
                        this.client.getEndpoint(),
                        chatThreadId,
                        maxPageSize,
                        skip,
                        this.client.getApiVersion(),
                        accept,
                        context)
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Gets the participants of a thread.
     *
     * @param chatThreadId Thread id to get participants for.
     * @param maxPageSize The maximum number of participants to be returned per page.
     * @param skip Skips participants up to a specified position in response.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the participants of a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<ChatParticipant> listChatParticipantsAsync(
            String chatThreadId, Integer maxPageSize, Integer skip) {
        return new PagedFlux<>(
                () -> listChatParticipantsSinglePageAsync(chatThreadId, maxPageSize, skip),
                nextLink -> listChatParticipantsNextSinglePageAsync(nextLink));
    }

    /**
     * Gets the participants of a thread.
     *
     * @param chatThreadId Thread id to get participants for.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the participants of a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<ChatParticipant> listChatParticipantsAsync(String chatThreadId) {
        final Integer maxPageSize = null;
        final Integer skip = null;
        return new PagedFlux<>(
                () -> listChatParticipantsSinglePageAsync(chatThreadId, maxPageSize, skip),
                nextLink -> listChatParticipantsNextSinglePageAsync(nextLink));
    }

    /**
     * Gets the participants of a thread.
     *
     * @param chatThreadId Thread id to get participants for.
     * @param maxPageSize The maximum number of participants to be returned per page.
     * @param skip Skips participants up to a specified position in response.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the participants of a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<ChatParticipant> listChatParticipantsAsync(
            String chatThreadId, Integer maxPageSize, Integer skip, Context context) {
        return new PagedFlux<>(
                () -> listChatParticipantsSinglePageAsync(chatThreadId, maxPageSize, skip, context),
                nextLink -> listChatParticipantsNextSinglePageAsync(nextLink, context));
    }

    /**
     * Gets the participants of a thread.
     *
     * @param chatThreadId Thread id to get participants for.
     * @param maxPageSize The maximum number of participants to be returned per page.
     * @param skip Skips participants up to a specified position in response.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the participants of a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedIterable<ChatParticipant> listChatParticipants(String chatThreadId, Integer maxPageSize, Integer skip) {
        return new PagedIterable<>(listChatParticipantsAsync(chatThreadId, maxPageSize, skip));
    }

    /**
     * Gets the participants of a thread.
     *
     * @param chatThreadId Thread id to get participants for.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the participants of a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedIterable<ChatParticipant> listChatParticipants(String chatThreadId) {
        final Integer maxPageSize = null;
        final Integer skip = null;
        return new PagedIterable<>(listChatParticipantsAsync(chatThreadId, maxPageSize, skip));
    }

    /**
     * Gets the participants of a thread.
     *
     * @param chatThreadId Thread id to get participants for.
     * @param maxPageSize The maximum number of participants to be returned per page.
     * @param skip Skips participants up to a specified position in response.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the participants of a thread.
     */
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedIterable<ChatParticipant> listChatParticipants(
            String chatThreadId, Integer maxPageSize, Integer skip, Context context) {
        return new PagedIterable<>(listChatParticipantsAsync(chatThreadId, maxPageSize, skip, context));
    }

    /**
     * Remove a participant from a thread.
     *
     * @param chatThreadId Thread id to remove the participant from.
     * @param participantCommunicationIdentifier Id of the thread participant to remove from the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> removeChatParticipantWithResponseAsync(
            String chatThreadId, CommunicationIdentifierModel participantCommunicationIdentifier) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                context ->
                        service.removeChatParticipant(
                                this.client.getEndpoint(),
                                chatThreadId,
                                this.client.getApiVersion(),
                                participantCommunicationIdentifier,
                                accept,
                                context));
    }

    /**
     * Remove a participant from a thread.
     *
     * @param chatThreadId Thread id to remove the participant from.
     * @param participantCommunicationIdentifier Id of the thread participant to remove from the thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> removeChatParticipantWithResponseAsync(
            String chatThreadId, CommunicationIdentifierModel participantCommunicationIdentifier, Context context) {
        final String accept = "application/json";
        return service.removeChatParticipant(
                this.client.getEndpoint(),
                chatThreadId,
                this.client.getApiVersion(),
                participantCommunicationIdentifier,
                accept,
                context);
    }

    /**
     * Remove a participant from a thread.
     *
     * @param chatThreadId Thread id to remove the participant from.
     * @param participantCommunicationIdentifier Id of the thread participant to remove from the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> removeChatParticipantAsync(
            String chatThreadId, CommunicationIdentifierModel participantCommunicationIdentifier) {
        return removeChatParticipantWithResponseAsync(chatThreadId, participantCommunicationIdentifier)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Remove a participant from a thread.
     *
     * @param chatThreadId Thread id to remove the participant from.
     * @param participantCommunicationIdentifier Id of the thread participant to remove from the thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> removeChatParticipantAsync(
            String chatThreadId, CommunicationIdentifierModel participantCommunicationIdentifier, Context context) {
        return removeChatParticipantWithResponseAsync(chatThreadId, participantCommunicationIdentifier, context)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Remove a participant from a thread.
     *
     * @param chatThreadId Thread id to remove the participant from.
     * @param participantCommunicationIdentifier Id of the thread participant to remove from the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public void removeChatParticipant(
            String chatThreadId, CommunicationIdentifierModel participantCommunicationIdentifier) {
        removeChatParticipantAsync(chatThreadId, participantCommunicationIdentifier).block();
    }

    /**
     * Remove a participant from a thread.
     *
     * @param chatThreadId Thread id to remove the participant from.
     * @param participantCommunicationIdentifier Id of the thread participant to remove from the thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the response.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Response<Void> removeChatParticipantWithResponse(
            String chatThreadId, CommunicationIdentifierModel participantCommunicationIdentifier, Context context) {
        return removeChatParticipantWithResponseAsync(chatThreadId, participantCommunicationIdentifier, context)
                .block();
    }

    /**
     * Adds thread participants to a thread. If participants already exist, no change occurs.
     *
     * @param chatThreadId Id of the thread to add participants to.
     * @param addChatParticipantsRequest Thread participants to be added to the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the add chat participants operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<AddChatParticipantsResult>> addChatParticipantsWithResponseAsync(
            String chatThreadId, AddChatParticipantsOptions addChatParticipantsRequest) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                context ->
                        service.addChatParticipants(
                                this.client.getEndpoint(),
                                chatThreadId,
                                this.client.getApiVersion(),
                                addChatParticipantsRequest,
                                accept,
                                context));
    }

    /**
     * Adds thread participants to a thread. If participants already exist, no change occurs.
     *
     * @param chatThreadId Id of the thread to add participants to.
     * @param addChatParticipantsRequest Thread participants to be added to the thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the add chat participants operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<AddChatParticipantsResult>> addChatParticipantsWithResponseAsync(
            String chatThreadId, AddChatParticipantsOptions addChatParticipantsRequest, Context context) {
        final String accept = "application/json";
        return service.addChatParticipants(
                this.client.getEndpoint(),
                chatThreadId,
                this.client.getApiVersion(),
                addChatParticipantsRequest,
                accept,
                context);
    }

    /**
     * Adds thread participants to a thread. If participants already exist, no change occurs.
     *
     * @param chatThreadId Id of the thread to add participants to.
     * @param addChatParticipantsRequest Thread participants to be added to the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the add chat participants operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<AddChatParticipantsResult> addChatParticipantsAsync(
            String chatThreadId, AddChatParticipantsOptions addChatParticipantsRequest) {
        return addChatParticipantsWithResponseAsync(chatThreadId, addChatParticipantsRequest)
                .flatMap(
                        (Response<AddChatParticipantsResult> res) -> {
                            if (res.getValue() != null) {
                                return Mono.just(res.getValue());
                            } else {
                                return Mono.empty();
                            }
                        });
    }

    /**
     * Adds thread participants to a thread. If participants already exist, no change occurs.
     *
     * @param chatThreadId Id of the thread to add participants to.
     * @param addChatParticipantsRequest Thread participants to be added to the thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the add chat participants operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<AddChatParticipantsResult> addChatParticipantsAsync(
            String chatThreadId, AddChatParticipantsOptions addChatParticipantsRequest, Context context) {
        return addChatParticipantsWithResponseAsync(chatThreadId, addChatParticipantsRequest, context)
                .flatMap(
                        (Response<AddChatParticipantsResult> res) -> {
                            if (res.getValue() != null) {
                                return Mono.just(res.getValue());
                            } else {
                                return Mono.empty();
                            }
                        });
    }

    /**
     * Adds thread participants to a thread. If participants already exist, no change occurs.
     *
     * @param chatThreadId Id of the thread to add participants to.
     * @param addChatParticipantsRequest Thread participants to be added to the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the add chat participants operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public AddChatParticipantsResult addChatParticipants(
            String chatThreadId, AddChatParticipantsOptions addChatParticipantsRequest) {
        return addChatParticipantsAsync(chatThreadId, addChatParticipantsRequest).block();
    }

    /**
     * Adds thread participants to a thread. If participants already exist, no change occurs.
     *
     * @param chatThreadId Id of the thread to add participants to.
     * @param addChatParticipantsRequest Thread participants to be added to the thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return result of the add chat participants operation.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Response<AddChatParticipantsResult> addChatParticipantsWithResponse(
            String chatThreadId, AddChatParticipantsOptions addChatParticipantsRequest, Context context) {
        return addChatParticipantsWithResponseAsync(chatThreadId, addChatParticipantsRequest, context).block();
    }

    /**
     * Updates a thread's properties.
     *
     * @param chatThreadId The id of the thread to update.
     * @param updateChatThreadRequest Request payload for updating a chat thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> updateChatThreadPropertiesWithResponseAsync(
            String chatThreadId, UpdateChatThreadOptions updateChatThreadRequest) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                context ->
                        service.updateChatThreadProperties(
                                this.client.getEndpoint(),
                                chatThreadId,
                                this.client.getApiVersion(),
                                updateChatThreadRequest,
                                accept,
                                context));
    }

    /**
     * Updates a thread's properties.
     *
     * @param chatThreadId The id of the thread to update.
     * @param updateChatThreadRequest Request payload for updating a chat thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> updateChatThreadPropertiesWithResponseAsync(
            String chatThreadId, UpdateChatThreadOptions updateChatThreadRequest, Context context) {
        final String accept = "application/json";
        return service.updateChatThreadProperties(
                this.client.getEndpoint(),
                chatThreadId,
                this.client.getApiVersion(),
                updateChatThreadRequest,
                accept,
                context);
    }

    /**
     * Updates a thread's properties.
     *
     * @param chatThreadId The id of the thread to update.
     * @param updateChatThreadRequest Request payload for updating a chat thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> updateChatThreadPropertiesAsync(
            String chatThreadId, UpdateChatThreadOptions updateChatThreadRequest) {
        return updateChatThreadPropertiesWithResponseAsync(chatThreadId, updateChatThreadRequest)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Updates a thread's properties.
     *
     * @param chatThreadId The id of the thread to update.
     * @param updateChatThreadRequest Request payload for updating a chat thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> updateChatThreadPropertiesAsync(
            String chatThreadId, UpdateChatThreadOptions updateChatThreadRequest, Context context) {
        return updateChatThreadPropertiesWithResponseAsync(chatThreadId, updateChatThreadRequest, context)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Updates a thread's properties.
     *
     * @param chatThreadId The id of the thread to update.
     * @param updateChatThreadRequest Request payload for updating a chat thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public void updateChatThreadProperties(String chatThreadId, UpdateChatThreadOptions updateChatThreadRequest) {
        updateChatThreadPropertiesAsync(chatThreadId, updateChatThreadRequest).block();
    }

    /**
     * Updates a thread's properties.
     *
     * @param chatThreadId The id of the thread to update.
     * @param updateChatThreadRequest Request payload for updating a chat thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the response.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Response<Void> updateChatThreadPropertiesWithResponse(
            String chatThreadId, UpdateChatThreadOptions updateChatThreadRequest, Context context) {
        return updateChatThreadPropertiesWithResponseAsync(chatThreadId, updateChatThreadRequest, context).block();
    }

    /**
     * Gets a chat thread's properties.
     *
     * @param chatThreadId Id of the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a chat thread's properties.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<ChatThreadProperties>> getChatThreadPropertiesWithResponseAsync(String chatThreadId) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                context ->
                        service.getChatThreadProperties(
                                this.client.getEndpoint(), chatThreadId, this.client.getApiVersion(), accept, context));
    }

    /**
     * Gets a chat thread's properties.
     *
     * @param chatThreadId Id of the thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a chat thread's properties.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<ChatThreadProperties>> getChatThreadPropertiesWithResponseAsync(
            String chatThreadId, Context context) {
        final String accept = "application/json";
        return service.getChatThreadProperties(
                this.client.getEndpoint(), chatThreadId, this.client.getApiVersion(), accept, context);
    }

    /**
     * Gets a chat thread's properties.
     *
     * @param chatThreadId Id of the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a chat thread's properties.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<ChatThreadProperties> getChatThreadPropertiesAsync(String chatThreadId) {
        return getChatThreadPropertiesWithResponseAsync(chatThreadId)
                .flatMap(
                        (Response<ChatThreadProperties> res) -> {
                            if (res.getValue() != null) {
                                return Mono.just(res.getValue());
                            } else {
                                return Mono.empty();
                            }
                        });
    }

    /**
     * Gets a chat thread's properties.
     *
     * @param chatThreadId Id of the thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a chat thread's properties.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<ChatThreadProperties> getChatThreadPropertiesAsync(String chatThreadId, Context context) {
        return getChatThreadPropertiesWithResponseAsync(chatThreadId, context)
                .flatMap(
                        (Response<ChatThreadProperties> res) -> {
                            if (res.getValue() != null) {
                                return Mono.just(res.getValue());
                            } else {
                                return Mono.empty();
                            }
                        });
    }

    /**
     * Gets a chat thread's properties.
     *
     * @param chatThreadId Id of the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a chat thread's properties.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public ChatThreadProperties getChatThreadProperties(String chatThreadId) {
        return getChatThreadPropertiesAsync(chatThreadId).block();
    }

    /**
     * Gets a chat thread's properties.
     *
     * @param chatThreadId Id of the thread.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a chat thread's properties.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Response<ChatThreadProperties> getChatThreadPropertiesWithResponse(String chatThreadId, Context context) {
        return getChatThreadPropertiesWithResponseAsync(chatThreadId, context).block();
    }

    /**
     * Posts a typing event to a thread, on behalf of a user.
     *
     * @param chatThreadId Id of the thread.
     * @param sendTypingNotificationRequest Details of the typing notification request.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> sendTypingNotificationWithResponseAsync(
            String chatThreadId, TypingNotificationOptions sendTypingNotificationRequest) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                context ->
                        service.sendTypingNotification(
                                this.client.getEndpoint(),
                                chatThreadId,
                                this.client.getApiVersion(),
                                sendTypingNotificationRequest,
                                accept,
                                context));
    }

    /**
     * Posts a typing event to a thread, on behalf of a user.
     *
     * @param chatThreadId Id of the thread.
     * @param sendTypingNotificationRequest Details of the typing notification request.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> sendTypingNotificationWithResponseAsync(
            String chatThreadId, TypingNotificationOptions sendTypingNotificationRequest, Context context) {
        final String accept = "application/json";
        return service.sendTypingNotification(
                this.client.getEndpoint(),
                chatThreadId,
                this.client.getApiVersion(),
                sendTypingNotificationRequest,
                accept,
                context);
    }

    /**
     * Posts a typing event to a thread, on behalf of a user.
     *
     * @param chatThreadId Id of the thread.
     * @param sendTypingNotificationRequest Details of the typing notification request.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> sendTypingNotificationAsync(
            String chatThreadId, TypingNotificationOptions sendTypingNotificationRequest) {
        return sendTypingNotificationWithResponseAsync(chatThreadId, sendTypingNotificationRequest)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Posts a typing event to a thread, on behalf of a user.
     *
     * @param chatThreadId Id of the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> sendTypingNotificationAsync(String chatThreadId) {
        final TypingNotificationOptions sendTypingNotificationRequest = null;
        return sendTypingNotificationWithResponseAsync(chatThreadId, sendTypingNotificationRequest)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Posts a typing event to a thread, on behalf of a user.
     *
     * @param chatThreadId Id of the thread.
     * @param sendTypingNotificationRequest Details of the typing notification request.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the completion.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Void> sendTypingNotificationAsync(
            String chatThreadId, TypingNotificationOptions sendTypingNotificationRequest, Context context) {
        return sendTypingNotificationWithResponseAsync(chatThreadId, sendTypingNotificationRequest, context)
                .flatMap((Response<Void> res) -> Mono.empty());
    }

    /**
     * Posts a typing event to a thread, on behalf of a user.
     *
     * @param chatThreadId Id of the thread.
     * @param sendTypingNotificationRequest Details of the typing notification request.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public void sendTypingNotification(String chatThreadId, TypingNotificationOptions sendTypingNotificationRequest) {
        sendTypingNotificationAsync(chatThreadId, sendTypingNotificationRequest).block();
    }

    /**
     * Posts a typing event to a thread, on behalf of a user.
     *
     * @param chatThreadId Id of the thread.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public void sendTypingNotification(String chatThreadId) {
        final TypingNotificationOptions sendTypingNotificationRequest = null;
        sendTypingNotificationAsync(chatThreadId, sendTypingNotificationRequest).block();
    }

    /**
     * Posts a typing event to a thread, on behalf of a user.
     *
     * @param chatThreadId Id of the thread.
     * @param sendTypingNotificationRequest Details of the typing notification request.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return the response.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Response<Void> sendTypingNotificationWithResponse(
            String chatThreadId, TypingNotificationOptions sendTypingNotificationRequest, Context context) {
        return sendTypingNotificationWithResponseAsync(chatThreadId, sendTypingNotificationRequest, context).block();
    }

    /**
     * Get the next page of items.
     *
     * @param nextLink The nextLink parameter.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a paged collection of chat message read receipts.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatMessageReadReceipt>> listChatReadReceiptsNextSinglePageAsync(String nextLink) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                        context ->
                                service.listChatReadReceiptsNext(nextLink, this.client.getEndpoint(), accept, context))
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Get the next page of items.
     *
     * @param nextLink The nextLink parameter.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return a paged collection of chat message read receipts.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatMessageReadReceipt>> listChatReadReceiptsNextSinglePageAsync(
            String nextLink, Context context) {
        final String accept = "application/json";
        return service.listChatReadReceiptsNext(nextLink, this.client.getEndpoint(), accept, context)
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Get the next page of items.
     *
     * @param nextLink The nextLink parameter.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return collection of chat messages for a particular chat thread.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatMessage>> listChatMessagesNextSinglePageAsync(String nextLink) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                        context -> service.listChatMessagesNext(nextLink, this.client.getEndpoint(), accept, context))
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Get the next page of items.
     *
     * @param nextLink The nextLink parameter.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return collection of chat messages for a particular chat thread.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatMessage>> listChatMessagesNextSinglePageAsync(String nextLink, Context context) {
        final String accept = "application/json";
        return service.listChatMessagesNext(nextLink, this.client.getEndpoint(), accept, context)
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Get the next page of items.
     *
     * @param nextLink The nextLink parameter.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return collection of participants belong to a particular thread.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatParticipant>> listChatParticipantsNextSinglePageAsync(String nextLink) {
        final String accept = "application/json";
        return FluxUtil.withContext(
                        context ->
                                service.listChatParticipantsNext(nextLink, this.client.getEndpoint(), accept, context))
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }

    /**
     * Get the next page of items.
     *
     * @param nextLink The nextLink parameter.
     * @param context The context to associate with this operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws CommunicationErrorResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return collection of participants belong to a particular thread.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<PagedResponse<ChatParticipant>> listChatParticipantsNextSinglePageAsync(
            String nextLink, Context context) {
        final String accept = "application/json";
        return service.listChatParticipantsNext(nextLink, this.client.getEndpoint(), accept, context)
                .map(
                        res ->
                                new PagedResponseBase<>(
                                        res.getRequest(),
                                        res.getStatusCode(),
                                        res.getHeaders(),
                                        res.getValue().getValue(),
                                        res.getValue().getNextLink(),
                                        null));
    }
}
