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

package com.azure.resourcemanager.apimanagement.implementation;

import com.azure.core.annotation.ServiceClient;
import com.azure.core.http.HttpHeaders;
import com.azure.core.http.HttpPipeline;
import com.azure.core.http.HttpResponse;
import com.azure.core.http.rest.Response;
import com.azure.core.management.AzureEnvironment;
import com.azure.core.management.exception.ManagementError;
import com.azure.core.management.exception.ManagementException;
import com.azure.core.management.polling.PollResult;
import com.azure.core.management.polling.PollerFactory;
import com.azure.core.util.Context;
import com.azure.core.util.logging.ClientLogger;
import com.azure.core.util.polling.AsyncPollResponse;
import com.azure.core.util.polling.LongRunningOperationStatus;
import com.azure.core.util.polling.PollerFlux;
import com.azure.core.util.serializer.SerializerAdapter;
import com.azure.core.util.serializer.SerializerEncoding;
import com.azure.resourcemanager.apimanagement.fluent.ApiDiagnosticsClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiExportsClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiIssueAttachmentsClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiIssueCommentsClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiIssuesClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiManagementClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiManagementOperationsClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiManagementServiceSkusClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiManagementServicesClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiManagementSkusClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiOperationPoliciesClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiOperationsClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiPoliciesClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiProductsClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiReleasesClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiRevisionsClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiSchemasClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiTagDescriptionsClient;
import com.azure.resourcemanager.apimanagement.fluent.ApiVersionSetsClient;
import com.azure.resourcemanager.apimanagement.fluent.ApisClient;
import com.azure.resourcemanager.apimanagement.fluent.AuthorizationServersClient;
import com.azure.resourcemanager.apimanagement.fluent.BackendsClient;
import com.azure.resourcemanager.apimanagement.fluent.CachesClient;
import com.azure.resourcemanager.apimanagement.fluent.CertificatesClient;
import com.azure.resourcemanager.apimanagement.fluent.ContentItemsClient;
import com.azure.resourcemanager.apimanagement.fluent.ContentTypesClient;
import com.azure.resourcemanager.apimanagement.fluent.DelegationSettingsClient;
import com.azure.resourcemanager.apimanagement.fluent.DeletedServicesClient;
import com.azure.resourcemanager.apimanagement.fluent.DiagnosticsClient;
import com.azure.resourcemanager.apimanagement.fluent.EmailTemplatesClient;
import com.azure.resourcemanager.apimanagement.fluent.GatewayApisClient;
import com.azure.resourcemanager.apimanagement.fluent.GatewayCertificateAuthoritiesClient;
import com.azure.resourcemanager.apimanagement.fluent.GatewayHostnameConfigurationsClient;
import com.azure.resourcemanager.apimanagement.fluent.GatewaysClient;
import com.azure.resourcemanager.apimanagement.fluent.GlobalSchemasClient;
import com.azure.resourcemanager.apimanagement.fluent.GroupUsersClient;
import com.azure.resourcemanager.apimanagement.fluent.GroupsClient;
import com.azure.resourcemanager.apimanagement.fluent.IdentityProvidersClient;
import com.azure.resourcemanager.apimanagement.fluent.IssuesClient;
import com.azure.resourcemanager.apimanagement.fluent.LoggersClient;
import com.azure.resourcemanager.apimanagement.fluent.NamedValuesClient;
import com.azure.resourcemanager.apimanagement.fluent.NetworkStatusClient;
import com.azure.resourcemanager.apimanagement.fluent.NotificationRecipientEmailsClient;
import com.azure.resourcemanager.apimanagement.fluent.NotificationRecipientUsersClient;
import com.azure.resourcemanager.apimanagement.fluent.NotificationsClient;
import com.azure.resourcemanager.apimanagement.fluent.OpenIdConnectProvidersClient;
import com.azure.resourcemanager.apimanagement.fluent.OperationsClient;
import com.azure.resourcemanager.apimanagement.fluent.OutboundNetworkDependenciesEndpointsClient;
import com.azure.resourcemanager.apimanagement.fluent.PoliciesClient;
import com.azure.resourcemanager.apimanagement.fluent.PolicyDescriptionsClient;
import com.azure.resourcemanager.apimanagement.fluent.PortalRevisionsClient;
import com.azure.resourcemanager.apimanagement.fluent.PortalSettingsClient;
import com.azure.resourcemanager.apimanagement.fluent.PrivateEndpointConnectionsClient;
import com.azure.resourcemanager.apimanagement.fluent.ProductApisClient;
import com.azure.resourcemanager.apimanagement.fluent.ProductGroupsClient;
import com.azure.resourcemanager.apimanagement.fluent.ProductPoliciesClient;
import com.azure.resourcemanager.apimanagement.fluent.ProductSubscriptionsClient;
import com.azure.resourcemanager.apimanagement.fluent.ProductsClient;
import com.azure.resourcemanager.apimanagement.fluent.QuotaByCounterKeysClient;
import com.azure.resourcemanager.apimanagement.fluent.QuotaByPeriodKeysClient;
import com.azure.resourcemanager.apimanagement.fluent.RegionsClient;
import com.azure.resourcemanager.apimanagement.fluent.ReportsClient;
import com.azure.resourcemanager.apimanagement.fluent.ResourceProvidersClient;
import com.azure.resourcemanager.apimanagement.fluent.SignInSettingsClient;
import com.azure.resourcemanager.apimanagement.fluent.SignUpSettingsClient;
import com.azure.resourcemanager.apimanagement.fluent.SubscriptionsClient;
import com.azure.resourcemanager.apimanagement.fluent.TagResourcesClient;
import com.azure.resourcemanager.apimanagement.fluent.TagsClient;
import com.azure.resourcemanager.apimanagement.fluent.TenantAccessClient;
import com.azure.resourcemanager.apimanagement.fluent.TenantAccessGitsClient;
import com.azure.resourcemanager.apimanagement.fluent.TenantConfigurationsClient;
import com.azure.resourcemanager.apimanagement.fluent.TenantSettingsClient;
import com.azure.resourcemanager.apimanagement.fluent.UserConfirmationPasswordsClient;
import com.azure.resourcemanager.apimanagement.fluent.UserGroupsClient;
import com.azure.resourcemanager.apimanagement.fluent.UserIdentitiesClient;
import com.azure.resourcemanager.apimanagement.fluent.UserSubscriptionsClient;
import com.azure.resourcemanager.apimanagement.fluent.UsersClient;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Map;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/** Initializes a new instance of the ApiManagementClientImpl type. */
@ServiceClient(builder = ApiManagementClientBuilder.class)
public final class ApiManagementClientImpl implements ApiManagementClient {
    /**
     * Subscription credentials which uniquely identify Microsoft Azure subscription. The subscription ID forms part of
     * the URI for every service call.
     */
    private final String subscriptionId;

    /**
     * Gets Subscription credentials which uniquely identify Microsoft Azure subscription. The subscription ID forms
     * part of the URI for every service call.
     *
     * @return the subscriptionId value.
     */
    public String getSubscriptionId() {
        return this.subscriptionId;
    }

    /** server parameter. */
    private final String endpoint;

    /**
     * Gets server parameter.
     *
     * @return the endpoint value.
     */
    public String getEndpoint() {
        return this.endpoint;
    }

    /** Api Version. */
    private final String apiVersion;

    /**
     * Gets Api Version.
     *
     * @return the apiVersion value.
     */
    public String getApiVersion() {
        return this.apiVersion;
    }

    /** The HTTP pipeline to send requests through. */
    private final HttpPipeline httpPipeline;

    /**
     * Gets The HTTP pipeline to send requests through.
     *
     * @return the httpPipeline value.
     */
    public HttpPipeline getHttpPipeline() {
        return this.httpPipeline;
    }

    /** The serializer to serialize an object into a string. */
    private final SerializerAdapter serializerAdapter;

    /**
     * Gets The serializer to serialize an object into a string.
     *
     * @return the serializerAdapter value.
     */
    SerializerAdapter getSerializerAdapter() {
        return this.serializerAdapter;
    }

    /** The default poll interval for long-running operation. */
    private final Duration defaultPollInterval;

    /**
     * Gets The default poll interval for long-running operation.
     *
     * @return the defaultPollInterval value.
     */
    public Duration getDefaultPollInterval() {
        return this.defaultPollInterval;
    }

    /** The ApisClient object to access its operations. */
    private final ApisClient apis;

    /**
     * Gets the ApisClient object to access its operations.
     *
     * @return the ApisClient object.
     */
    public ApisClient getApis() {
        return this.apis;
    }

    /** The ApiRevisionsClient object to access its operations. */
    private final ApiRevisionsClient apiRevisions;

    /**
     * Gets the ApiRevisionsClient object to access its operations.
     *
     * @return the ApiRevisionsClient object.
     */
    public ApiRevisionsClient getApiRevisions() {
        return this.apiRevisions;
    }

    /** The ApiReleasesClient object to access its operations. */
    private final ApiReleasesClient apiReleases;

    /**
     * Gets the ApiReleasesClient object to access its operations.
     *
     * @return the ApiReleasesClient object.
     */
    public ApiReleasesClient getApiReleases() {
        return this.apiReleases;
    }

    /** The ApiOperationsClient object to access its operations. */
    private final ApiOperationsClient apiOperations;

    /**
     * Gets the ApiOperationsClient object to access its operations.
     *
     * @return the ApiOperationsClient object.
     */
    public ApiOperationsClient getApiOperations() {
        return this.apiOperations;
    }

    /** The ApiOperationPoliciesClient object to access its operations. */
    private final ApiOperationPoliciesClient apiOperationPolicies;

    /**
     * Gets the ApiOperationPoliciesClient object to access its operations.
     *
     * @return the ApiOperationPoliciesClient object.
     */
    public ApiOperationPoliciesClient getApiOperationPolicies() {
        return this.apiOperationPolicies;
    }

    /** The TagsClient object to access its operations. */
    private final TagsClient tags;

    /**
     * Gets the TagsClient object to access its operations.
     *
     * @return the TagsClient object.
     */
    public TagsClient getTags() {
        return this.tags;
    }

    /** The ApiProductsClient object to access its operations. */
    private final ApiProductsClient apiProducts;

    /**
     * Gets the ApiProductsClient object to access its operations.
     *
     * @return the ApiProductsClient object.
     */
    public ApiProductsClient getApiProducts() {
        return this.apiProducts;
    }

    /** The ApiPoliciesClient object to access its operations. */
    private final ApiPoliciesClient apiPolicies;

    /**
     * Gets the ApiPoliciesClient object to access its operations.
     *
     * @return the ApiPoliciesClient object.
     */
    public ApiPoliciesClient getApiPolicies() {
        return this.apiPolicies;
    }

    /** The ApiSchemasClient object to access its operations. */
    private final ApiSchemasClient apiSchemas;

    /**
     * Gets the ApiSchemasClient object to access its operations.
     *
     * @return the ApiSchemasClient object.
     */
    public ApiSchemasClient getApiSchemas() {
        return this.apiSchemas;
    }

    /** The ApiDiagnosticsClient object to access its operations. */
    private final ApiDiagnosticsClient apiDiagnostics;

    /**
     * Gets the ApiDiagnosticsClient object to access its operations.
     *
     * @return the ApiDiagnosticsClient object.
     */
    public ApiDiagnosticsClient getApiDiagnostics() {
        return this.apiDiagnostics;
    }

    /** The ApiIssuesClient object to access its operations. */
    private final ApiIssuesClient apiIssues;

    /**
     * Gets the ApiIssuesClient object to access its operations.
     *
     * @return the ApiIssuesClient object.
     */
    public ApiIssuesClient getApiIssues() {
        return this.apiIssues;
    }

    /** The ApiIssueCommentsClient object to access its operations. */
    private final ApiIssueCommentsClient apiIssueComments;

    /**
     * Gets the ApiIssueCommentsClient object to access its operations.
     *
     * @return the ApiIssueCommentsClient object.
     */
    public ApiIssueCommentsClient getApiIssueComments() {
        return this.apiIssueComments;
    }

    /** The ApiIssueAttachmentsClient object to access its operations. */
    private final ApiIssueAttachmentsClient apiIssueAttachments;

    /**
     * Gets the ApiIssueAttachmentsClient object to access its operations.
     *
     * @return the ApiIssueAttachmentsClient object.
     */
    public ApiIssueAttachmentsClient getApiIssueAttachments() {
        return this.apiIssueAttachments;
    }

    /** The ApiTagDescriptionsClient object to access its operations. */
    private final ApiTagDescriptionsClient apiTagDescriptions;

    /**
     * Gets the ApiTagDescriptionsClient object to access its operations.
     *
     * @return the ApiTagDescriptionsClient object.
     */
    public ApiTagDescriptionsClient getApiTagDescriptions() {
        return this.apiTagDescriptions;
    }

    /** The OperationsClient object to access its operations. */
    private final OperationsClient operations;

    /**
     * Gets the OperationsClient object to access its operations.
     *
     * @return the OperationsClient object.
     */
    public OperationsClient getOperations() {
        return this.operations;
    }

    /** The ApiExportsClient object to access its operations. */
    private final ApiExportsClient apiExports;

    /**
     * Gets the ApiExportsClient object to access its operations.
     *
     * @return the ApiExportsClient object.
     */
    public ApiExportsClient getApiExports() {
        return this.apiExports;
    }

    /** The ApiVersionSetsClient object to access its operations. */
    private final ApiVersionSetsClient apiVersionSets;

    /**
     * Gets the ApiVersionSetsClient object to access its operations.
     *
     * @return the ApiVersionSetsClient object.
     */
    public ApiVersionSetsClient getApiVersionSets() {
        return this.apiVersionSets;
    }

    /** The AuthorizationServersClient object to access its operations. */
    private final AuthorizationServersClient authorizationServers;

    /**
     * Gets the AuthorizationServersClient object to access its operations.
     *
     * @return the AuthorizationServersClient object.
     */
    public AuthorizationServersClient getAuthorizationServers() {
        return this.authorizationServers;
    }

    /** The BackendsClient object to access its operations. */
    private final BackendsClient backends;

    /**
     * Gets the BackendsClient object to access its operations.
     *
     * @return the BackendsClient object.
     */
    public BackendsClient getBackends() {
        return this.backends;
    }

    /** The CachesClient object to access its operations. */
    private final CachesClient caches;

    /**
     * Gets the CachesClient object to access its operations.
     *
     * @return the CachesClient object.
     */
    public CachesClient getCaches() {
        return this.caches;
    }

    /** The CertificatesClient object to access its operations. */
    private final CertificatesClient certificates;

    /**
     * Gets the CertificatesClient object to access its operations.
     *
     * @return the CertificatesClient object.
     */
    public CertificatesClient getCertificates() {
        return this.certificates;
    }

    /** The ResourceProvidersClient object to access its operations. */
    private final ResourceProvidersClient resourceProviders;

    /**
     * Gets the ResourceProvidersClient object to access its operations.
     *
     * @return the ResourceProvidersClient object.
     */
    public ResourceProvidersClient getResourceProviders() {
        return this.resourceProviders;
    }

    /** The ContentTypesClient object to access its operations. */
    private final ContentTypesClient contentTypes;

    /**
     * Gets the ContentTypesClient object to access its operations.
     *
     * @return the ContentTypesClient object.
     */
    public ContentTypesClient getContentTypes() {
        return this.contentTypes;
    }

    /** The ContentItemsClient object to access its operations. */
    private final ContentItemsClient contentItems;

    /**
     * Gets the ContentItemsClient object to access its operations.
     *
     * @return the ContentItemsClient object.
     */
    public ContentItemsClient getContentItems() {
        return this.contentItems;
    }

    /** The DeletedServicesClient object to access its operations. */
    private final DeletedServicesClient deletedServices;

    /**
     * Gets the DeletedServicesClient object to access its operations.
     *
     * @return the DeletedServicesClient object.
     */
    public DeletedServicesClient getDeletedServices() {
        return this.deletedServices;
    }

    /** The ApiManagementOperationsClient object to access its operations. */
    private final ApiManagementOperationsClient apiManagementOperations;

    /**
     * Gets the ApiManagementOperationsClient object to access its operations.
     *
     * @return the ApiManagementOperationsClient object.
     */
    public ApiManagementOperationsClient getApiManagementOperations() {
        return this.apiManagementOperations;
    }

    /** The ApiManagementServiceSkusClient object to access its operations. */
    private final ApiManagementServiceSkusClient apiManagementServiceSkus;

    /**
     * Gets the ApiManagementServiceSkusClient object to access its operations.
     *
     * @return the ApiManagementServiceSkusClient object.
     */
    public ApiManagementServiceSkusClient getApiManagementServiceSkus() {
        return this.apiManagementServiceSkus;
    }

    /** The ApiManagementServicesClient object to access its operations. */
    private final ApiManagementServicesClient apiManagementServices;

    /**
     * Gets the ApiManagementServicesClient object to access its operations.
     *
     * @return the ApiManagementServicesClient object.
     */
    public ApiManagementServicesClient getApiManagementServices() {
        return this.apiManagementServices;
    }

    /** The DiagnosticsClient object to access its operations. */
    private final DiagnosticsClient diagnostics;

    /**
     * Gets the DiagnosticsClient object to access its operations.
     *
     * @return the DiagnosticsClient object.
     */
    public DiagnosticsClient getDiagnostics() {
        return this.diagnostics;
    }

    /** The EmailTemplatesClient object to access its operations. */
    private final EmailTemplatesClient emailTemplates;

    /**
     * Gets the EmailTemplatesClient object to access its operations.
     *
     * @return the EmailTemplatesClient object.
     */
    public EmailTemplatesClient getEmailTemplates() {
        return this.emailTemplates;
    }

    /** The GatewaysClient object to access its operations. */
    private final GatewaysClient gateways;

    /**
     * Gets the GatewaysClient object to access its operations.
     *
     * @return the GatewaysClient object.
     */
    public GatewaysClient getGateways() {
        return this.gateways;
    }

    /** The GatewayHostnameConfigurationsClient object to access its operations. */
    private final GatewayHostnameConfigurationsClient gatewayHostnameConfigurations;

    /**
     * Gets the GatewayHostnameConfigurationsClient object to access its operations.
     *
     * @return the GatewayHostnameConfigurationsClient object.
     */
    public GatewayHostnameConfigurationsClient getGatewayHostnameConfigurations() {
        return this.gatewayHostnameConfigurations;
    }

    /** The GatewayApisClient object to access its operations. */
    private final GatewayApisClient gatewayApis;

    /**
     * Gets the GatewayApisClient object to access its operations.
     *
     * @return the GatewayApisClient object.
     */
    public GatewayApisClient getGatewayApis() {
        return this.gatewayApis;
    }

    /** The GatewayCertificateAuthoritiesClient object to access its operations. */
    private final GatewayCertificateAuthoritiesClient gatewayCertificateAuthorities;

    /**
     * Gets the GatewayCertificateAuthoritiesClient object to access its operations.
     *
     * @return the GatewayCertificateAuthoritiesClient object.
     */
    public GatewayCertificateAuthoritiesClient getGatewayCertificateAuthorities() {
        return this.gatewayCertificateAuthorities;
    }

    /** The GroupsClient object to access its operations. */
    private final GroupsClient groups;

    /**
     * Gets the GroupsClient object to access its operations.
     *
     * @return the GroupsClient object.
     */
    public GroupsClient getGroups() {
        return this.groups;
    }

    /** The GroupUsersClient object to access its operations. */
    private final GroupUsersClient groupUsers;

    /**
     * Gets the GroupUsersClient object to access its operations.
     *
     * @return the GroupUsersClient object.
     */
    public GroupUsersClient getGroupUsers() {
        return this.groupUsers;
    }

    /** The IdentityProvidersClient object to access its operations. */
    private final IdentityProvidersClient identityProviders;

    /**
     * Gets the IdentityProvidersClient object to access its operations.
     *
     * @return the IdentityProvidersClient object.
     */
    public IdentityProvidersClient getIdentityProviders() {
        return this.identityProviders;
    }

    /** The IssuesClient object to access its operations. */
    private final IssuesClient issues;

    /**
     * Gets the IssuesClient object to access its operations.
     *
     * @return the IssuesClient object.
     */
    public IssuesClient getIssues() {
        return this.issues;
    }

    /** The LoggersClient object to access its operations. */
    private final LoggersClient loggers;

    /**
     * Gets the LoggersClient object to access its operations.
     *
     * @return the LoggersClient object.
     */
    public LoggersClient getLoggers() {
        return this.loggers;
    }

    /** The NamedValuesClient object to access its operations. */
    private final NamedValuesClient namedValues;

    /**
     * Gets the NamedValuesClient object to access its operations.
     *
     * @return the NamedValuesClient object.
     */
    public NamedValuesClient getNamedValues() {
        return this.namedValues;
    }

    /** The NetworkStatusClient object to access its operations. */
    private final NetworkStatusClient networkStatus;

    /**
     * Gets the NetworkStatusClient object to access its operations.
     *
     * @return the NetworkStatusClient object.
     */
    public NetworkStatusClient getNetworkStatus() {
        return this.networkStatus;
    }

    /** The NotificationsClient object to access its operations. */
    private final NotificationsClient notifications;

    /**
     * Gets the NotificationsClient object to access its operations.
     *
     * @return the NotificationsClient object.
     */
    public NotificationsClient getNotifications() {
        return this.notifications;
    }

    /** The NotificationRecipientUsersClient object to access its operations. */
    private final NotificationRecipientUsersClient notificationRecipientUsers;

    /**
     * Gets the NotificationRecipientUsersClient object to access its operations.
     *
     * @return the NotificationRecipientUsersClient object.
     */
    public NotificationRecipientUsersClient getNotificationRecipientUsers() {
        return this.notificationRecipientUsers;
    }

    /** The NotificationRecipientEmailsClient object to access its operations. */
    private final NotificationRecipientEmailsClient notificationRecipientEmails;

    /**
     * Gets the NotificationRecipientEmailsClient object to access its operations.
     *
     * @return the NotificationRecipientEmailsClient object.
     */
    public NotificationRecipientEmailsClient getNotificationRecipientEmails() {
        return this.notificationRecipientEmails;
    }

    /** The OpenIdConnectProvidersClient object to access its operations. */
    private final OpenIdConnectProvidersClient openIdConnectProviders;

    /**
     * Gets the OpenIdConnectProvidersClient object to access its operations.
     *
     * @return the OpenIdConnectProvidersClient object.
     */
    public OpenIdConnectProvidersClient getOpenIdConnectProviders() {
        return this.openIdConnectProviders;
    }

    /** The OutboundNetworkDependenciesEndpointsClient object to access its operations. */
    private final OutboundNetworkDependenciesEndpointsClient outboundNetworkDependenciesEndpoints;

    /**
     * Gets the OutboundNetworkDependenciesEndpointsClient object to access its operations.
     *
     * @return the OutboundNetworkDependenciesEndpointsClient object.
     */
    public OutboundNetworkDependenciesEndpointsClient getOutboundNetworkDependenciesEndpoints() {
        return this.outboundNetworkDependenciesEndpoints;
    }

    /** The PoliciesClient object to access its operations. */
    private final PoliciesClient policies;

    /**
     * Gets the PoliciesClient object to access its operations.
     *
     * @return the PoliciesClient object.
     */
    public PoliciesClient getPolicies() {
        return this.policies;
    }

    /** The PolicyDescriptionsClient object to access its operations. */
    private final PolicyDescriptionsClient policyDescriptions;

    /**
     * Gets the PolicyDescriptionsClient object to access its operations.
     *
     * @return the PolicyDescriptionsClient object.
     */
    public PolicyDescriptionsClient getPolicyDescriptions() {
        return this.policyDescriptions;
    }

    /** The PortalRevisionsClient object to access its operations. */
    private final PortalRevisionsClient portalRevisions;

    /**
     * Gets the PortalRevisionsClient object to access its operations.
     *
     * @return the PortalRevisionsClient object.
     */
    public PortalRevisionsClient getPortalRevisions() {
        return this.portalRevisions;
    }

    /** The PortalSettingsClient object to access its operations. */
    private final PortalSettingsClient portalSettings;

    /**
     * Gets the PortalSettingsClient object to access its operations.
     *
     * @return the PortalSettingsClient object.
     */
    public PortalSettingsClient getPortalSettings() {
        return this.portalSettings;
    }

    /** The SignInSettingsClient object to access its operations. */
    private final SignInSettingsClient signInSettings;

    /**
     * Gets the SignInSettingsClient object to access its operations.
     *
     * @return the SignInSettingsClient object.
     */
    public SignInSettingsClient getSignInSettings() {
        return this.signInSettings;
    }

    /** The SignUpSettingsClient object to access its operations. */
    private final SignUpSettingsClient signUpSettings;

    /**
     * Gets the SignUpSettingsClient object to access its operations.
     *
     * @return the SignUpSettingsClient object.
     */
    public SignUpSettingsClient getSignUpSettings() {
        return this.signUpSettings;
    }

    /** The DelegationSettingsClient object to access its operations. */
    private final DelegationSettingsClient delegationSettings;

    /**
     * Gets the DelegationSettingsClient object to access its operations.
     *
     * @return the DelegationSettingsClient object.
     */
    public DelegationSettingsClient getDelegationSettings() {
        return this.delegationSettings;
    }

    /** The PrivateEndpointConnectionsClient object to access its operations. */
    private final PrivateEndpointConnectionsClient privateEndpointConnections;

    /**
     * Gets the PrivateEndpointConnectionsClient object to access its operations.
     *
     * @return the PrivateEndpointConnectionsClient object.
     */
    public PrivateEndpointConnectionsClient getPrivateEndpointConnections() {
        return this.privateEndpointConnections;
    }

    /** The ProductsClient object to access its operations. */
    private final ProductsClient products;

    /**
     * Gets the ProductsClient object to access its operations.
     *
     * @return the ProductsClient object.
     */
    public ProductsClient getProducts() {
        return this.products;
    }

    /** The ProductApisClient object to access its operations. */
    private final ProductApisClient productApis;

    /**
     * Gets the ProductApisClient object to access its operations.
     *
     * @return the ProductApisClient object.
     */
    public ProductApisClient getProductApis() {
        return this.productApis;
    }

    /** The ProductGroupsClient object to access its operations. */
    private final ProductGroupsClient productGroups;

    /**
     * Gets the ProductGroupsClient object to access its operations.
     *
     * @return the ProductGroupsClient object.
     */
    public ProductGroupsClient getProductGroups() {
        return this.productGroups;
    }

    /** The ProductSubscriptionsClient object to access its operations. */
    private final ProductSubscriptionsClient productSubscriptions;

    /**
     * Gets the ProductSubscriptionsClient object to access its operations.
     *
     * @return the ProductSubscriptionsClient object.
     */
    public ProductSubscriptionsClient getProductSubscriptions() {
        return this.productSubscriptions;
    }

    /** The ProductPoliciesClient object to access its operations. */
    private final ProductPoliciesClient productPolicies;

    /**
     * Gets the ProductPoliciesClient object to access its operations.
     *
     * @return the ProductPoliciesClient object.
     */
    public ProductPoliciesClient getProductPolicies() {
        return this.productPolicies;
    }

    /** The QuotaByCounterKeysClient object to access its operations. */
    private final QuotaByCounterKeysClient quotaByCounterKeys;

    /**
     * Gets the QuotaByCounterKeysClient object to access its operations.
     *
     * @return the QuotaByCounterKeysClient object.
     */
    public QuotaByCounterKeysClient getQuotaByCounterKeys() {
        return this.quotaByCounterKeys;
    }

    /** The QuotaByPeriodKeysClient object to access its operations. */
    private final QuotaByPeriodKeysClient quotaByPeriodKeys;

    /**
     * Gets the QuotaByPeriodKeysClient object to access its operations.
     *
     * @return the QuotaByPeriodKeysClient object.
     */
    public QuotaByPeriodKeysClient getQuotaByPeriodKeys() {
        return this.quotaByPeriodKeys;
    }

    /** The RegionsClient object to access its operations. */
    private final RegionsClient regions;

    /**
     * Gets the RegionsClient object to access its operations.
     *
     * @return the RegionsClient object.
     */
    public RegionsClient getRegions() {
        return this.regions;
    }

    /** The ReportsClient object to access its operations. */
    private final ReportsClient reports;

    /**
     * Gets the ReportsClient object to access its operations.
     *
     * @return the ReportsClient object.
     */
    public ReportsClient getReports() {
        return this.reports;
    }

    /** The GlobalSchemasClient object to access its operations. */
    private final GlobalSchemasClient globalSchemas;

    /**
     * Gets the GlobalSchemasClient object to access its operations.
     *
     * @return the GlobalSchemasClient object.
     */
    public GlobalSchemasClient getGlobalSchemas() {
        return this.globalSchemas;
    }

    /** The TenantSettingsClient object to access its operations. */
    private final TenantSettingsClient tenantSettings;

    /**
     * Gets the TenantSettingsClient object to access its operations.
     *
     * @return the TenantSettingsClient object.
     */
    public TenantSettingsClient getTenantSettings() {
        return this.tenantSettings;
    }

    /** The ApiManagementSkusClient object to access its operations. */
    private final ApiManagementSkusClient apiManagementSkus;

    /**
     * Gets the ApiManagementSkusClient object to access its operations.
     *
     * @return the ApiManagementSkusClient object.
     */
    public ApiManagementSkusClient getApiManagementSkus() {
        return this.apiManagementSkus;
    }

    /** The SubscriptionsClient object to access its operations. */
    private final SubscriptionsClient subscriptions;

    /**
     * Gets the SubscriptionsClient object to access its operations.
     *
     * @return the SubscriptionsClient object.
     */
    public SubscriptionsClient getSubscriptions() {
        return this.subscriptions;
    }

    /** The TagResourcesClient object to access its operations. */
    private final TagResourcesClient tagResources;

    /**
     * Gets the TagResourcesClient object to access its operations.
     *
     * @return the TagResourcesClient object.
     */
    public TagResourcesClient getTagResources() {
        return this.tagResources;
    }

    /** The TenantAccessClient object to access its operations. */
    private final TenantAccessClient tenantAccess;

    /**
     * Gets the TenantAccessClient object to access its operations.
     *
     * @return the TenantAccessClient object.
     */
    public TenantAccessClient getTenantAccess() {
        return this.tenantAccess;
    }

    /** The TenantAccessGitsClient object to access its operations. */
    private final TenantAccessGitsClient tenantAccessGits;

    /**
     * Gets the TenantAccessGitsClient object to access its operations.
     *
     * @return the TenantAccessGitsClient object.
     */
    public TenantAccessGitsClient getTenantAccessGits() {
        return this.tenantAccessGits;
    }

    /** The TenantConfigurationsClient object to access its operations. */
    private final TenantConfigurationsClient tenantConfigurations;

    /**
     * Gets the TenantConfigurationsClient object to access its operations.
     *
     * @return the TenantConfigurationsClient object.
     */
    public TenantConfigurationsClient getTenantConfigurations() {
        return this.tenantConfigurations;
    }

    /** The UsersClient object to access its operations. */
    private final UsersClient users;

    /**
     * Gets the UsersClient object to access its operations.
     *
     * @return the UsersClient object.
     */
    public UsersClient getUsers() {
        return this.users;
    }

    /** The UserGroupsClient object to access its operations. */
    private final UserGroupsClient userGroups;

    /**
     * Gets the UserGroupsClient object to access its operations.
     *
     * @return the UserGroupsClient object.
     */
    public UserGroupsClient getUserGroups() {
        return this.userGroups;
    }

    /** The UserSubscriptionsClient object to access its operations. */
    private final UserSubscriptionsClient userSubscriptions;

    /**
     * Gets the UserSubscriptionsClient object to access its operations.
     *
     * @return the UserSubscriptionsClient object.
     */
    public UserSubscriptionsClient getUserSubscriptions() {
        return this.userSubscriptions;
    }

    /** The UserIdentitiesClient object to access its operations. */
    private final UserIdentitiesClient userIdentities;

    /**
     * Gets the UserIdentitiesClient object to access its operations.
     *
     * @return the UserIdentitiesClient object.
     */
    public UserIdentitiesClient getUserIdentities() {
        return this.userIdentities;
    }

    /** The UserConfirmationPasswordsClient object to access its operations. */
    private final UserConfirmationPasswordsClient userConfirmationPasswords;

    /**
     * Gets the UserConfirmationPasswordsClient object to access its operations.
     *
     * @return the UserConfirmationPasswordsClient object.
     */
    public UserConfirmationPasswordsClient getUserConfirmationPasswords() {
        return this.userConfirmationPasswords;
    }

    /**
     * Initializes an instance of ApiManagementClient client.
     *
     * @param httpPipeline The HTTP pipeline to send requests through.
     * @param serializerAdapter The serializer to serialize an object into a string.
     * @param defaultPollInterval The default poll interval for long-running operation.
     * @param environment The Azure environment.
     * @param subscriptionId Subscription credentials which uniquely identify Microsoft Azure subscription. The
     *     subscription ID forms part of the URI for every service call.
     * @param endpoint server parameter.
     */
    ApiManagementClientImpl(
        HttpPipeline httpPipeline,
        SerializerAdapter serializerAdapter,
        Duration defaultPollInterval,
        AzureEnvironment environment,
        String subscriptionId,
        String endpoint) {
        this.httpPipeline = httpPipeline;
        this.serializerAdapter = serializerAdapter;
        this.defaultPollInterval = defaultPollInterval;
        this.subscriptionId = subscriptionId;
        this.endpoint = endpoint;
        this.apiVersion = "2021-08-01";
        this.apis = new ApisClientImpl(this);
        this.apiRevisions = new ApiRevisionsClientImpl(this);
        this.apiReleases = new ApiReleasesClientImpl(this);
        this.apiOperations = new ApiOperationsClientImpl(this);
        this.apiOperationPolicies = new ApiOperationPoliciesClientImpl(this);
        this.tags = new TagsClientImpl(this);
        this.apiProducts = new ApiProductsClientImpl(this);
        this.apiPolicies = new ApiPoliciesClientImpl(this);
        this.apiSchemas = new ApiSchemasClientImpl(this);
        this.apiDiagnostics = new ApiDiagnosticsClientImpl(this);
        this.apiIssues = new ApiIssuesClientImpl(this);
        this.apiIssueComments = new ApiIssueCommentsClientImpl(this);
        this.apiIssueAttachments = new ApiIssueAttachmentsClientImpl(this);
        this.apiTagDescriptions = new ApiTagDescriptionsClientImpl(this);
        this.operations = new OperationsClientImpl(this);
        this.apiExports = new ApiExportsClientImpl(this);
        this.apiVersionSets = new ApiVersionSetsClientImpl(this);
        this.authorizationServers = new AuthorizationServersClientImpl(this);
        this.backends = new BackendsClientImpl(this);
        this.caches = new CachesClientImpl(this);
        this.certificates = new CertificatesClientImpl(this);
        this.resourceProviders = new ResourceProvidersClientImpl(this);
        this.contentTypes = new ContentTypesClientImpl(this);
        this.contentItems = new ContentItemsClientImpl(this);
        this.deletedServices = new DeletedServicesClientImpl(this);
        this.apiManagementOperations = new ApiManagementOperationsClientImpl(this);
        this.apiManagementServiceSkus = new ApiManagementServiceSkusClientImpl(this);
        this.apiManagementServices = new ApiManagementServicesClientImpl(this);
        this.diagnostics = new DiagnosticsClientImpl(this);
        this.emailTemplates = new EmailTemplatesClientImpl(this);
        this.gateways = new GatewaysClientImpl(this);
        this.gatewayHostnameConfigurations = new GatewayHostnameConfigurationsClientImpl(this);
        this.gatewayApis = new GatewayApisClientImpl(this);
        this.gatewayCertificateAuthorities = new GatewayCertificateAuthoritiesClientImpl(this);
        this.groups = new GroupsClientImpl(this);
        this.groupUsers = new GroupUsersClientImpl(this);
        this.identityProviders = new IdentityProvidersClientImpl(this);
        this.issues = new IssuesClientImpl(this);
        this.loggers = new LoggersClientImpl(this);
        this.namedValues = new NamedValuesClientImpl(this);
        this.networkStatus = new NetworkStatusClientImpl(this);
        this.notifications = new NotificationsClientImpl(this);
        this.notificationRecipientUsers = new NotificationRecipientUsersClientImpl(this);
        this.notificationRecipientEmails = new NotificationRecipientEmailsClientImpl(this);
        this.openIdConnectProviders = new OpenIdConnectProvidersClientImpl(this);
        this.outboundNetworkDependenciesEndpoints = new OutboundNetworkDependenciesEndpointsClientImpl(this);
        this.policies = new PoliciesClientImpl(this);
        this.policyDescriptions = new PolicyDescriptionsClientImpl(this);
        this.portalRevisions = new PortalRevisionsClientImpl(this);
        this.portalSettings = new PortalSettingsClientImpl(this);
        this.signInSettings = new SignInSettingsClientImpl(this);
        this.signUpSettings = new SignUpSettingsClientImpl(this);
        this.delegationSettings = new DelegationSettingsClientImpl(this);
        this.privateEndpointConnections = new PrivateEndpointConnectionsClientImpl(this);
        this.products = new ProductsClientImpl(this);
        this.productApis = new ProductApisClientImpl(this);
        this.productGroups = new ProductGroupsClientImpl(this);
        this.productSubscriptions = new ProductSubscriptionsClientImpl(this);
        this.productPolicies = new ProductPoliciesClientImpl(this);
        this.quotaByCounterKeys = new QuotaByCounterKeysClientImpl(this);
        this.quotaByPeriodKeys = new QuotaByPeriodKeysClientImpl(this);
        this.regions = new RegionsClientImpl(this);
        this.reports = new ReportsClientImpl(this);
        this.globalSchemas = new GlobalSchemasClientImpl(this);
        this.tenantSettings = new TenantSettingsClientImpl(this);
        this.apiManagementSkus = new ApiManagementSkusClientImpl(this);
        this.subscriptions = new SubscriptionsClientImpl(this);
        this.tagResources = new TagResourcesClientImpl(this);
        this.tenantAccess = new TenantAccessClientImpl(this);
        this.tenantAccessGits = new TenantAccessGitsClientImpl(this);
        this.tenantConfigurations = new TenantConfigurationsClientImpl(this);
        this.users = new UsersClientImpl(this);
        this.userGroups = new UserGroupsClientImpl(this);
        this.userSubscriptions = new UserSubscriptionsClientImpl(this);
        this.userIdentities = new UserIdentitiesClientImpl(this);
        this.userConfirmationPasswords = new UserConfirmationPasswordsClientImpl(this);
    }

    /**
     * Gets default client context.
     *
     * @return the default client context.
     */
    public Context getContext() {
        return Context.NONE;
    }

    /**
     * Merges default client context with provided context.
     *
     * @param context the context to be merged with default client context.
     * @return the merged context.
     */
    public Context mergeContext(Context context) {
        for (Map.Entry<Object, Object> entry : this.getContext().getValues().entrySet()) {
            context = context.addData(entry.getKey(), entry.getValue());
        }
        return context;
    }

    /**
     * Gets long running operation result.
     *
     * @param activationResponse the response of activation operation.
     * @param httpPipeline the http pipeline.
     * @param pollResultType type of poll result.
     * @param finalResultType type of final result.
     * @param context the context shared by all requests.
     * @param <T> type of poll result.
     * @param <U> type of final result.
     * @return poller flux for poll result and final result.
     */
    public <T, U> PollerFlux<PollResult<T>, U> getLroResult(
        Mono<Response<Flux<ByteBuffer>>> activationResponse,
        HttpPipeline httpPipeline,
        Type pollResultType,
        Type finalResultType,
        Context context) {
        return PollerFactory
            .create(
                serializerAdapter,
                httpPipeline,
                pollResultType,
                finalResultType,
                defaultPollInterval,
                activationResponse,
                context);
    }

    /**
     * Gets the final result, or an error, based on last async poll response.
     *
     * @param response the last async poll response.
     * @param <T> type of poll result.
     * @param <U> type of final result.
     * @return the final result, or an error.
     */
    public <T, U> Mono<U> getLroFinalResultOrError(AsyncPollResponse<PollResult<T>, U> response) {
        if (response.getStatus() != LongRunningOperationStatus.SUCCESSFULLY_COMPLETED) {
            String errorMessage;
            ManagementError managementError = null;
            HttpResponse errorResponse = null;
            PollResult.Error lroError = response.getValue().getError();
            if (lroError != null) {
                errorResponse =
                    new HttpResponseImpl(
                        lroError.getResponseStatusCode(), lroError.getResponseHeaders(), lroError.getResponseBody());

                errorMessage = response.getValue().getError().getMessage();
                String errorBody = response.getValue().getError().getResponseBody();
                if (errorBody != null) {
                    // try to deserialize error body to ManagementError
                    try {
                        managementError =
                            this
                                .getSerializerAdapter()
                                .deserialize(errorBody, ManagementError.class, SerializerEncoding.JSON);
                        if (managementError.getCode() == null || managementError.getMessage() == null) {
                            managementError = null;
                        }
                    } catch (IOException | RuntimeException ioe) {
                        LOGGER.logThrowableAsWarning(ioe);
                    }
                }
            } else {
                // fallback to default error message
                errorMessage = "Long running operation failed.";
            }
            if (managementError == null) {
                // fallback to default ManagementError
                managementError = new ManagementError(response.getStatus().toString(), errorMessage);
            }
            return Mono.error(new ManagementException(errorMessage, errorResponse, managementError));
        } else {
            return response.getFinalResult();
        }
    }

    private static final class HttpResponseImpl extends HttpResponse {
        private final int statusCode;

        private final byte[] responseBody;

        private final HttpHeaders httpHeaders;

        HttpResponseImpl(int statusCode, HttpHeaders httpHeaders, String responseBody) {
            super(null);
            this.statusCode = statusCode;
            this.httpHeaders = httpHeaders;
            this.responseBody = responseBody == null ? null : responseBody.getBytes(StandardCharsets.UTF_8);
        }

        public int getStatusCode() {
            return statusCode;
        }

        public String getHeaderValue(String s) {
            return httpHeaders.getValue(s);
        }

        public HttpHeaders getHeaders() {
            return httpHeaders;
        }

        public Flux<ByteBuffer> getBody() {
            return Flux.just(ByteBuffer.wrap(responseBody));
        }

        public Mono<byte[]> getBodyAsByteArray() {
            return Mono.just(responseBody);
        }

        public Mono<String> getBodyAsString() {
            return Mono.just(new String(responseBody, StandardCharsets.UTF_8));
        }

        public Mono<String> getBodyAsString(Charset charset) {
            return Mono.just(new String(responseBody, charset));
        }
    }

    private static final ClientLogger LOGGER = new ClientLogger(ApiManagementClientImpl.class);
}
