// 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;

import com.azure.core.credential.TokenCredential;
import com.azure.core.http.HttpClient;
import com.azure.core.http.HttpPipeline;
import com.azure.core.http.HttpPipelineBuilder;
import com.azure.core.http.HttpPipelinePosition;
import com.azure.core.http.policy.AddDatePolicy;
import com.azure.core.http.policy.HttpLogOptions;
import com.azure.core.http.policy.HttpLoggingPolicy;
import com.azure.core.http.policy.HttpPipelinePolicy;
import com.azure.core.http.policy.HttpPolicyProviders;
import com.azure.core.http.policy.RequestIdPolicy;
import com.azure.core.http.policy.RetryPolicy;
import com.azure.core.http.policy.UserAgentPolicy;
import com.azure.core.management.http.policy.ArmChallengeAuthenticationPolicy;
import com.azure.core.management.profile.AzureProfile;
import com.azure.core.util.Configuration;
import com.azure.core.util.logging.ClientLogger;
import com.azure.resourcemanager.apimanagement.fluent.ApiManagementClient;
import com.azure.resourcemanager.apimanagement.implementation.ApiDiagnosticsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiExportsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiIssueAttachmentsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiIssueCommentsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiIssuesImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiManagementClientBuilder;
import com.azure.resourcemanager.apimanagement.implementation.ApiManagementOperationsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiManagementServiceSkusImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiManagementServicesImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiManagementSkusImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiOperationPoliciesImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiOperationsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiPoliciesImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiProductsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiReleasesImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiRevisionsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiSchemasImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiTagDescriptionsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApiVersionSetsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ApisImpl;
import com.azure.resourcemanager.apimanagement.implementation.AuthorizationServersImpl;
import com.azure.resourcemanager.apimanagement.implementation.BackendsImpl;
import com.azure.resourcemanager.apimanagement.implementation.CachesImpl;
import com.azure.resourcemanager.apimanagement.implementation.CertificatesImpl;
import com.azure.resourcemanager.apimanagement.implementation.ContentItemsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ContentTypesImpl;
import com.azure.resourcemanager.apimanagement.implementation.DelegationSettingsImpl;
import com.azure.resourcemanager.apimanagement.implementation.DeletedServicesImpl;
import com.azure.resourcemanager.apimanagement.implementation.DiagnosticsImpl;
import com.azure.resourcemanager.apimanagement.implementation.EmailTemplatesImpl;
import com.azure.resourcemanager.apimanagement.implementation.GatewayApisImpl;
import com.azure.resourcemanager.apimanagement.implementation.GatewayCertificateAuthoritiesImpl;
import com.azure.resourcemanager.apimanagement.implementation.GatewayHostnameConfigurationsImpl;
import com.azure.resourcemanager.apimanagement.implementation.GatewaysImpl;
import com.azure.resourcemanager.apimanagement.implementation.GlobalSchemasImpl;
import com.azure.resourcemanager.apimanagement.implementation.GroupUsersImpl;
import com.azure.resourcemanager.apimanagement.implementation.GroupsImpl;
import com.azure.resourcemanager.apimanagement.implementation.IdentityProvidersImpl;
import com.azure.resourcemanager.apimanagement.implementation.IssuesImpl;
import com.azure.resourcemanager.apimanagement.implementation.LoggersImpl;
import com.azure.resourcemanager.apimanagement.implementation.NamedValuesImpl;
import com.azure.resourcemanager.apimanagement.implementation.NetworkStatusImpl;
import com.azure.resourcemanager.apimanagement.implementation.NotificationRecipientEmailsImpl;
import com.azure.resourcemanager.apimanagement.implementation.NotificationRecipientUsersImpl;
import com.azure.resourcemanager.apimanagement.implementation.NotificationsImpl;
import com.azure.resourcemanager.apimanagement.implementation.OpenIdConnectProvidersImpl;
import com.azure.resourcemanager.apimanagement.implementation.OperationsImpl;
import com.azure.resourcemanager.apimanagement.implementation.OutboundNetworkDependenciesEndpointsImpl;
import com.azure.resourcemanager.apimanagement.implementation.PoliciesImpl;
import com.azure.resourcemanager.apimanagement.implementation.PolicyDescriptionsImpl;
import com.azure.resourcemanager.apimanagement.implementation.PortalRevisionsImpl;
import com.azure.resourcemanager.apimanagement.implementation.PortalSettingsImpl;
import com.azure.resourcemanager.apimanagement.implementation.PrivateEndpointConnectionsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ProductApisImpl;
import com.azure.resourcemanager.apimanagement.implementation.ProductGroupsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ProductPoliciesImpl;
import com.azure.resourcemanager.apimanagement.implementation.ProductSubscriptionsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ProductsImpl;
import com.azure.resourcemanager.apimanagement.implementation.QuotaByCounterKeysImpl;
import com.azure.resourcemanager.apimanagement.implementation.QuotaByPeriodKeysImpl;
import com.azure.resourcemanager.apimanagement.implementation.RegionsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ReportsImpl;
import com.azure.resourcemanager.apimanagement.implementation.ResourceProvidersImpl;
import com.azure.resourcemanager.apimanagement.implementation.SignInSettingsImpl;
import com.azure.resourcemanager.apimanagement.implementation.SignUpSettingsImpl;
import com.azure.resourcemanager.apimanagement.implementation.SubscriptionsImpl;
import com.azure.resourcemanager.apimanagement.implementation.TagResourcesImpl;
import com.azure.resourcemanager.apimanagement.implementation.TagsImpl;
import com.azure.resourcemanager.apimanagement.implementation.TenantAccessGitsImpl;
import com.azure.resourcemanager.apimanagement.implementation.TenantAccessImpl;
import com.azure.resourcemanager.apimanagement.implementation.TenantConfigurationsImpl;
import com.azure.resourcemanager.apimanagement.implementation.TenantSettingsImpl;
import com.azure.resourcemanager.apimanagement.implementation.UserConfirmationPasswordsImpl;
import com.azure.resourcemanager.apimanagement.implementation.UserGroupsImpl;
import com.azure.resourcemanager.apimanagement.implementation.UserIdentitiesImpl;
import com.azure.resourcemanager.apimanagement.implementation.UserSubscriptionsImpl;
import com.azure.resourcemanager.apimanagement.implementation.UsersImpl;
import com.azure.resourcemanager.apimanagement.models.ApiDiagnostics;
import com.azure.resourcemanager.apimanagement.models.ApiExports;
import com.azure.resourcemanager.apimanagement.models.ApiIssueAttachments;
import com.azure.resourcemanager.apimanagement.models.ApiIssueComments;
import com.azure.resourcemanager.apimanagement.models.ApiIssues;
import com.azure.resourcemanager.apimanagement.models.ApiManagementOperations;
import com.azure.resourcemanager.apimanagement.models.ApiManagementServiceSkus;
import com.azure.resourcemanager.apimanagement.models.ApiManagementServices;
import com.azure.resourcemanager.apimanagement.models.ApiManagementSkus;
import com.azure.resourcemanager.apimanagement.models.ApiOperationPolicies;
import com.azure.resourcemanager.apimanagement.models.ApiOperations;
import com.azure.resourcemanager.apimanagement.models.ApiPolicies;
import com.azure.resourcemanager.apimanagement.models.ApiProducts;
import com.azure.resourcemanager.apimanagement.models.ApiReleases;
import com.azure.resourcemanager.apimanagement.models.ApiRevisions;
import com.azure.resourcemanager.apimanagement.models.ApiSchemas;
import com.azure.resourcemanager.apimanagement.models.ApiTagDescriptions;
import com.azure.resourcemanager.apimanagement.models.ApiVersionSets;
import com.azure.resourcemanager.apimanagement.models.Apis;
import com.azure.resourcemanager.apimanagement.models.AuthorizationServers;
import com.azure.resourcemanager.apimanagement.models.Backends;
import com.azure.resourcemanager.apimanagement.models.Caches;
import com.azure.resourcemanager.apimanagement.models.Certificates;
import com.azure.resourcemanager.apimanagement.models.ContentItems;
import com.azure.resourcemanager.apimanagement.models.ContentTypes;
import com.azure.resourcemanager.apimanagement.models.DelegationSettings;
import com.azure.resourcemanager.apimanagement.models.DeletedServices;
import com.azure.resourcemanager.apimanagement.models.Diagnostics;
import com.azure.resourcemanager.apimanagement.models.EmailTemplates;
import com.azure.resourcemanager.apimanagement.models.GatewayApis;
import com.azure.resourcemanager.apimanagement.models.GatewayCertificateAuthorities;
import com.azure.resourcemanager.apimanagement.models.GatewayHostnameConfigurations;
import com.azure.resourcemanager.apimanagement.models.Gateways;
import com.azure.resourcemanager.apimanagement.models.GlobalSchemas;
import com.azure.resourcemanager.apimanagement.models.GroupUsers;
import com.azure.resourcemanager.apimanagement.models.Groups;
import com.azure.resourcemanager.apimanagement.models.IdentityProviders;
import com.azure.resourcemanager.apimanagement.models.Issues;
import com.azure.resourcemanager.apimanagement.models.Loggers;
import com.azure.resourcemanager.apimanagement.models.NamedValues;
import com.azure.resourcemanager.apimanagement.models.NetworkStatus;
import com.azure.resourcemanager.apimanagement.models.NotificationRecipientEmails;
import com.azure.resourcemanager.apimanagement.models.NotificationRecipientUsers;
import com.azure.resourcemanager.apimanagement.models.Notifications;
import com.azure.resourcemanager.apimanagement.models.OpenIdConnectProviders;
import com.azure.resourcemanager.apimanagement.models.Operations;
import com.azure.resourcemanager.apimanagement.models.OutboundNetworkDependenciesEndpoints;
import com.azure.resourcemanager.apimanagement.models.Policies;
import com.azure.resourcemanager.apimanagement.models.PolicyDescriptions;
import com.azure.resourcemanager.apimanagement.models.PortalRevisions;
import com.azure.resourcemanager.apimanagement.models.PortalSettings;
import com.azure.resourcemanager.apimanagement.models.PrivateEndpointConnections;
import com.azure.resourcemanager.apimanagement.models.ProductApis;
import com.azure.resourcemanager.apimanagement.models.ProductGroups;
import com.azure.resourcemanager.apimanagement.models.ProductPolicies;
import com.azure.resourcemanager.apimanagement.models.ProductSubscriptions;
import com.azure.resourcemanager.apimanagement.models.Products;
import com.azure.resourcemanager.apimanagement.models.QuotaByCounterKeys;
import com.azure.resourcemanager.apimanagement.models.QuotaByPeriodKeys;
import com.azure.resourcemanager.apimanagement.models.Regions;
import com.azure.resourcemanager.apimanagement.models.Reports;
import com.azure.resourcemanager.apimanagement.models.ResourceProviders;
import com.azure.resourcemanager.apimanagement.models.SignInSettings;
import com.azure.resourcemanager.apimanagement.models.SignUpSettings;
import com.azure.resourcemanager.apimanagement.models.Subscriptions;
import com.azure.resourcemanager.apimanagement.models.TagResources;
import com.azure.resourcemanager.apimanagement.models.Tags;
import com.azure.resourcemanager.apimanagement.models.TenantAccess;
import com.azure.resourcemanager.apimanagement.models.TenantAccessGits;
import com.azure.resourcemanager.apimanagement.models.TenantConfigurations;
import com.azure.resourcemanager.apimanagement.models.TenantSettings;
import com.azure.resourcemanager.apimanagement.models.UserConfirmationPasswords;
import com.azure.resourcemanager.apimanagement.models.UserGroups;
import com.azure.resourcemanager.apimanagement.models.UserIdentities;
import com.azure.resourcemanager.apimanagement.models.UserSubscriptions;
import com.azure.resourcemanager.apimanagement.models.Users;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/** Entry point to ApiManagementManager. ApiManagement Client. */
public final class ApiManagementManager {
    private Apis apis;

    private ApiRevisions apiRevisions;

    private ApiReleases apiReleases;

    private ApiOperations apiOperations;

    private ApiOperationPolicies apiOperationPolicies;

    private Tags tags;

    private ApiProducts apiProducts;

    private ApiPolicies apiPolicies;

    private ApiSchemas apiSchemas;

    private ApiDiagnostics apiDiagnostics;

    private ApiIssues apiIssues;

    private ApiIssueComments apiIssueComments;

    private ApiIssueAttachments apiIssueAttachments;

    private ApiTagDescriptions apiTagDescriptions;

    private Operations operations;

    private ApiExports apiExports;

    private ApiVersionSets apiVersionSets;

    private AuthorizationServers authorizationServers;

    private Backends backends;

    private Caches caches;

    private Certificates certificates;

    private ResourceProviders resourceProviders;

    private ContentTypes contentTypes;

    private ContentItems contentItems;

    private DeletedServices deletedServices;

    private ApiManagementOperations apiManagementOperations;

    private ApiManagementServiceSkus apiManagementServiceSkus;

    private ApiManagementServices apiManagementServices;

    private Diagnostics diagnostics;

    private EmailTemplates emailTemplates;

    private Gateways gateways;

    private GatewayHostnameConfigurations gatewayHostnameConfigurations;

    private GatewayApis gatewayApis;

    private GatewayCertificateAuthorities gatewayCertificateAuthorities;

    private Groups groups;

    private GroupUsers groupUsers;

    private IdentityProviders identityProviders;

    private Issues issues;

    private Loggers loggers;

    private NamedValues namedValues;

    private NetworkStatus networkStatus;

    private Notifications notifications;

    private NotificationRecipientUsers notificationRecipientUsers;

    private NotificationRecipientEmails notificationRecipientEmails;

    private OpenIdConnectProviders openIdConnectProviders;

    private OutboundNetworkDependenciesEndpoints outboundNetworkDependenciesEndpoints;

    private Policies policies;

    private PolicyDescriptions policyDescriptions;

    private PortalRevisions portalRevisions;

    private PortalSettings portalSettings;

    private SignInSettings signInSettings;

    private SignUpSettings signUpSettings;

    private DelegationSettings delegationSettings;

    private PrivateEndpointConnections privateEndpointConnections;

    private Products products;

    private ProductApis productApis;

    private ProductGroups productGroups;

    private ProductSubscriptions productSubscriptions;

    private ProductPolicies productPolicies;

    private QuotaByCounterKeys quotaByCounterKeys;

    private QuotaByPeriodKeys quotaByPeriodKeys;

    private Regions regions;

    private Reports reports;

    private GlobalSchemas globalSchemas;

    private TenantSettings tenantSettings;

    private ApiManagementSkus apiManagementSkus;

    private Subscriptions subscriptions;

    private TagResources tagResources;

    private TenantAccess tenantAccess;

    private TenantAccessGits tenantAccessGits;

    private TenantConfigurations tenantConfigurations;

    private Users users;

    private UserGroups userGroups;

    private UserSubscriptions userSubscriptions;

    private UserIdentities userIdentities;

    private UserConfirmationPasswords userConfirmationPasswords;

    private final ApiManagementClient clientObject;

    private ApiManagementManager(HttpPipeline httpPipeline, AzureProfile profile, Duration defaultPollInterval) {
        Objects.requireNonNull(httpPipeline, "'httpPipeline' cannot be null.");
        Objects.requireNonNull(profile, "'profile' cannot be null.");
        this.clientObject =
            new ApiManagementClientBuilder()
                .pipeline(httpPipeline)
                .endpoint(profile.getEnvironment().getResourceManagerEndpoint())
                .subscriptionId(profile.getSubscriptionId())
                .defaultPollInterval(defaultPollInterval)
                .buildClient();
    }

    /**
     * Creates an instance of ApiManagement service API entry point.
     *
     * @param credential the credential to use.
     * @param profile the Azure profile for client.
     * @return the ApiManagement service API instance.
     */
    public static ApiManagementManager authenticate(TokenCredential credential, AzureProfile profile) {
        Objects.requireNonNull(credential, "'credential' cannot be null.");
        Objects.requireNonNull(profile, "'profile' cannot be null.");
        return configure().authenticate(credential, profile);
    }

    /**
     * Gets a Configurable instance that can be used to create ApiManagementManager with optional configuration.
     *
     * @return the Configurable instance allowing configurations.
     */
    public static Configurable configure() {
        return new ApiManagementManager.Configurable();
    }

    /** The Configurable allowing configurations to be set. */
    public static final class Configurable {
        private static final ClientLogger LOGGER = new ClientLogger(Configurable.class);

        private HttpClient httpClient;
        private HttpLogOptions httpLogOptions;
        private final List<HttpPipelinePolicy> policies = new ArrayList<>();
        private final List<String> scopes = new ArrayList<>();
        private RetryPolicy retryPolicy;
        private Duration defaultPollInterval;

        private Configurable() {
        }

        /**
         * Sets the http client.
         *
         * @param httpClient the HTTP client.
         * @return the configurable object itself.
         */
        public Configurable withHttpClient(HttpClient httpClient) {
            this.httpClient = Objects.requireNonNull(httpClient, "'httpClient' cannot be null.");
            return this;
        }

        /**
         * Sets the logging options to the HTTP pipeline.
         *
         * @param httpLogOptions the HTTP log options.
         * @return the configurable object itself.
         */
        public Configurable withLogOptions(HttpLogOptions httpLogOptions) {
            this.httpLogOptions = Objects.requireNonNull(httpLogOptions, "'httpLogOptions' cannot be null.");
            return this;
        }

        /**
         * Adds the pipeline policy to the HTTP pipeline.
         *
         * @param policy the HTTP pipeline policy.
         * @return the configurable object itself.
         */
        public Configurable withPolicy(HttpPipelinePolicy policy) {
            this.policies.add(Objects.requireNonNull(policy, "'policy' cannot be null."));
            return this;
        }

        /**
         * Adds the scope to permission sets.
         *
         * @param scope the scope.
         * @return the configurable object itself.
         */
        public Configurable withScope(String scope) {
            this.scopes.add(Objects.requireNonNull(scope, "'scope' cannot be null."));
            return this;
        }

        /**
         * Sets the retry policy to the HTTP pipeline.
         *
         * @param retryPolicy the HTTP pipeline retry policy.
         * @return the configurable object itself.
         */
        public Configurable withRetryPolicy(RetryPolicy retryPolicy) {
            this.retryPolicy = Objects.requireNonNull(retryPolicy, "'retryPolicy' cannot be null.");
            return this;
        }

        /**
         * Sets the default poll interval, used when service does not provide "Retry-After" header.
         *
         * @param defaultPollInterval the default poll interval.
         * @return the configurable object itself.
         */
        public Configurable withDefaultPollInterval(Duration defaultPollInterval) {
            this.defaultPollInterval =
                Objects.requireNonNull(defaultPollInterval, "'defaultPollInterval' cannot be null.");
            if (this.defaultPollInterval.isNegative()) {
                throw LOGGER
                    .logExceptionAsError(new IllegalArgumentException("'defaultPollInterval' cannot be negative"));
            }
            return this;
        }

        /**
         * Creates an instance of ApiManagement service API entry point.
         *
         * @param credential the credential to use.
         * @param profile the Azure profile for client.
         * @return the ApiManagement service API instance.
         */
        public ApiManagementManager authenticate(TokenCredential credential, AzureProfile profile) {
            Objects.requireNonNull(credential, "'credential' cannot be null.");
            Objects.requireNonNull(profile, "'profile' cannot be null.");

            StringBuilder userAgentBuilder = new StringBuilder();
            userAgentBuilder
                .append("azsdk-java")
                .append("-")
                .append("com.azure.resourcemanager.apimanagement")
                .append("/")
                .append("1.0.0-beta.3");
            if (!Configuration.getGlobalConfiguration().get("AZURE_TELEMETRY_DISABLED", false)) {
                userAgentBuilder
                    .append(" (")
                    .append(Configuration.getGlobalConfiguration().get("java.version"))
                    .append("; ")
                    .append(Configuration.getGlobalConfiguration().get("os.name"))
                    .append("; ")
                    .append(Configuration.getGlobalConfiguration().get("os.version"))
                    .append("; auto-generated)");
            } else {
                userAgentBuilder.append(" (auto-generated)");
            }

            if (scopes.isEmpty()) {
                scopes.add(profile.getEnvironment().getManagementEndpoint() + "/.default");
            }
            if (retryPolicy == null) {
                retryPolicy = new RetryPolicy("Retry-After", ChronoUnit.SECONDS);
            }
            List<HttpPipelinePolicy> policies = new ArrayList<>();
            policies.add(new UserAgentPolicy(userAgentBuilder.toString()));
            policies.add(new RequestIdPolicy());
            policies
                .addAll(
                    this
                        .policies
                        .stream()
                        .filter(p -> p.getPipelinePosition() == HttpPipelinePosition.PER_CALL)
                        .collect(Collectors.toList()));
            HttpPolicyProviders.addBeforeRetryPolicies(policies);
            policies.add(retryPolicy);
            policies.add(new AddDatePolicy());
            policies.add(new ArmChallengeAuthenticationPolicy(credential, scopes.toArray(new String[0])));
            policies
                .addAll(
                    this
                        .policies
                        .stream()
                        .filter(p -> p.getPipelinePosition() == HttpPipelinePosition.PER_RETRY)
                        .collect(Collectors.toList()));
            HttpPolicyProviders.addAfterRetryPolicies(policies);
            policies.add(new HttpLoggingPolicy(httpLogOptions));
            HttpPipeline httpPipeline =
                new HttpPipelineBuilder()
                    .httpClient(httpClient)
                    .policies(policies.toArray(new HttpPipelinePolicy[0]))
                    .build();
            return new ApiManagementManager(httpPipeline, profile, defaultPollInterval);
        }
    }

    /** @return Resource collection API of Apis. */
    public Apis apis() {
        if (this.apis == null) {
            this.apis = new ApisImpl(clientObject.getApis(), this);
        }
        return apis;
    }

    /** @return Resource collection API of ApiRevisions. */
    public ApiRevisions apiRevisions() {
        if (this.apiRevisions == null) {
            this.apiRevisions = new ApiRevisionsImpl(clientObject.getApiRevisions(), this);
        }
        return apiRevisions;
    }

    /** @return Resource collection API of ApiReleases. */
    public ApiReleases apiReleases() {
        if (this.apiReleases == null) {
            this.apiReleases = new ApiReleasesImpl(clientObject.getApiReleases(), this);
        }
        return apiReleases;
    }

    /** @return Resource collection API of ApiOperations. */
    public ApiOperations apiOperations() {
        if (this.apiOperations == null) {
            this.apiOperations = new ApiOperationsImpl(clientObject.getApiOperations(), this);
        }
        return apiOperations;
    }

    /** @return Resource collection API of ApiOperationPolicies. */
    public ApiOperationPolicies apiOperationPolicies() {
        if (this.apiOperationPolicies == null) {
            this.apiOperationPolicies = new ApiOperationPoliciesImpl(clientObject.getApiOperationPolicies(), this);
        }
        return apiOperationPolicies;
    }

    /** @return Resource collection API of Tags. */
    public Tags tags() {
        if (this.tags == null) {
            this.tags = new TagsImpl(clientObject.getTags(), this);
        }
        return tags;
    }

    /** @return Resource collection API of ApiProducts. */
    public ApiProducts apiProducts() {
        if (this.apiProducts == null) {
            this.apiProducts = new ApiProductsImpl(clientObject.getApiProducts(), this);
        }
        return apiProducts;
    }

    /** @return Resource collection API of ApiPolicies. */
    public ApiPolicies apiPolicies() {
        if (this.apiPolicies == null) {
            this.apiPolicies = new ApiPoliciesImpl(clientObject.getApiPolicies(), this);
        }
        return apiPolicies;
    }

    /** @return Resource collection API of ApiSchemas. */
    public ApiSchemas apiSchemas() {
        if (this.apiSchemas == null) {
            this.apiSchemas = new ApiSchemasImpl(clientObject.getApiSchemas(), this);
        }
        return apiSchemas;
    }

    /** @return Resource collection API of ApiDiagnostics. */
    public ApiDiagnostics apiDiagnostics() {
        if (this.apiDiagnostics == null) {
            this.apiDiagnostics = new ApiDiagnosticsImpl(clientObject.getApiDiagnostics(), this);
        }
        return apiDiagnostics;
    }

    /** @return Resource collection API of ApiIssues. */
    public ApiIssues apiIssues() {
        if (this.apiIssues == null) {
            this.apiIssues = new ApiIssuesImpl(clientObject.getApiIssues(), this);
        }
        return apiIssues;
    }

    /** @return Resource collection API of ApiIssueComments. */
    public ApiIssueComments apiIssueComments() {
        if (this.apiIssueComments == null) {
            this.apiIssueComments = new ApiIssueCommentsImpl(clientObject.getApiIssueComments(), this);
        }
        return apiIssueComments;
    }

    /** @return Resource collection API of ApiIssueAttachments. */
    public ApiIssueAttachments apiIssueAttachments() {
        if (this.apiIssueAttachments == null) {
            this.apiIssueAttachments = new ApiIssueAttachmentsImpl(clientObject.getApiIssueAttachments(), this);
        }
        return apiIssueAttachments;
    }

    /** @return Resource collection API of ApiTagDescriptions. */
    public ApiTagDescriptions apiTagDescriptions() {
        if (this.apiTagDescriptions == null) {
            this.apiTagDescriptions = new ApiTagDescriptionsImpl(clientObject.getApiTagDescriptions(), this);
        }
        return apiTagDescriptions;
    }

    /** @return Resource collection API of Operations. */
    public Operations operations() {
        if (this.operations == null) {
            this.operations = new OperationsImpl(clientObject.getOperations(), this);
        }
        return operations;
    }

    /** @return Resource collection API of ApiExports. */
    public ApiExports apiExports() {
        if (this.apiExports == null) {
            this.apiExports = new ApiExportsImpl(clientObject.getApiExports(), this);
        }
        return apiExports;
    }

    /** @return Resource collection API of ApiVersionSets. */
    public ApiVersionSets apiVersionSets() {
        if (this.apiVersionSets == null) {
            this.apiVersionSets = new ApiVersionSetsImpl(clientObject.getApiVersionSets(), this);
        }
        return apiVersionSets;
    }

    /** @return Resource collection API of AuthorizationServers. */
    public AuthorizationServers authorizationServers() {
        if (this.authorizationServers == null) {
            this.authorizationServers = new AuthorizationServersImpl(clientObject.getAuthorizationServers(), this);
        }
        return authorizationServers;
    }

    /** @return Resource collection API of Backends. */
    public Backends backends() {
        if (this.backends == null) {
            this.backends = new BackendsImpl(clientObject.getBackends(), this);
        }
        return backends;
    }

    /** @return Resource collection API of Caches. */
    public Caches caches() {
        if (this.caches == null) {
            this.caches = new CachesImpl(clientObject.getCaches(), this);
        }
        return caches;
    }

    /** @return Resource collection API of Certificates. */
    public Certificates certificates() {
        if (this.certificates == null) {
            this.certificates = new CertificatesImpl(clientObject.getCertificates(), this);
        }
        return certificates;
    }

    /** @return Resource collection API of ResourceProviders. */
    public ResourceProviders resourceProviders() {
        if (this.resourceProviders == null) {
            this.resourceProviders = new ResourceProvidersImpl(clientObject.getResourceProviders(), this);
        }
        return resourceProviders;
    }

    /** @return Resource collection API of ContentTypes. */
    public ContentTypes contentTypes() {
        if (this.contentTypes == null) {
            this.contentTypes = new ContentTypesImpl(clientObject.getContentTypes(), this);
        }
        return contentTypes;
    }

    /** @return Resource collection API of ContentItems. */
    public ContentItems contentItems() {
        if (this.contentItems == null) {
            this.contentItems = new ContentItemsImpl(clientObject.getContentItems(), this);
        }
        return contentItems;
    }

    /** @return Resource collection API of DeletedServices. */
    public DeletedServices deletedServices() {
        if (this.deletedServices == null) {
            this.deletedServices = new DeletedServicesImpl(clientObject.getDeletedServices(), this);
        }
        return deletedServices;
    }

    /** @return Resource collection API of ApiManagementOperations. */
    public ApiManagementOperations apiManagementOperations() {
        if (this.apiManagementOperations == null) {
            this.apiManagementOperations =
                new ApiManagementOperationsImpl(clientObject.getApiManagementOperations(), this);
        }
        return apiManagementOperations;
    }

    /** @return Resource collection API of ApiManagementServiceSkus. */
    public ApiManagementServiceSkus apiManagementServiceSkus() {
        if (this.apiManagementServiceSkus == null) {
            this.apiManagementServiceSkus =
                new ApiManagementServiceSkusImpl(clientObject.getApiManagementServiceSkus(), this);
        }
        return apiManagementServiceSkus;
    }

    /** @return Resource collection API of ApiManagementServices. */
    public ApiManagementServices apiManagementServices() {
        if (this.apiManagementServices == null) {
            this.apiManagementServices = new ApiManagementServicesImpl(clientObject.getApiManagementServices(), this);
        }
        return apiManagementServices;
    }

    /** @return Resource collection API of Diagnostics. */
    public Diagnostics diagnostics() {
        if (this.diagnostics == null) {
            this.diagnostics = new DiagnosticsImpl(clientObject.getDiagnostics(), this);
        }
        return diagnostics;
    }

    /** @return Resource collection API of EmailTemplates. */
    public EmailTemplates emailTemplates() {
        if (this.emailTemplates == null) {
            this.emailTemplates = new EmailTemplatesImpl(clientObject.getEmailTemplates(), this);
        }
        return emailTemplates;
    }

    /** @return Resource collection API of Gateways. */
    public Gateways gateways() {
        if (this.gateways == null) {
            this.gateways = new GatewaysImpl(clientObject.getGateways(), this);
        }
        return gateways;
    }

    /** @return Resource collection API of GatewayHostnameConfigurations. */
    public GatewayHostnameConfigurations gatewayHostnameConfigurations() {
        if (this.gatewayHostnameConfigurations == null) {
            this.gatewayHostnameConfigurations =
                new GatewayHostnameConfigurationsImpl(clientObject.getGatewayHostnameConfigurations(), this);
        }
        return gatewayHostnameConfigurations;
    }

    /** @return Resource collection API of GatewayApis. */
    public GatewayApis gatewayApis() {
        if (this.gatewayApis == null) {
            this.gatewayApis = new GatewayApisImpl(clientObject.getGatewayApis(), this);
        }
        return gatewayApis;
    }

    /** @return Resource collection API of GatewayCertificateAuthorities. */
    public GatewayCertificateAuthorities gatewayCertificateAuthorities() {
        if (this.gatewayCertificateAuthorities == null) {
            this.gatewayCertificateAuthorities =
                new GatewayCertificateAuthoritiesImpl(clientObject.getGatewayCertificateAuthorities(), this);
        }
        return gatewayCertificateAuthorities;
    }

    /** @return Resource collection API of Groups. */
    public Groups groups() {
        if (this.groups == null) {
            this.groups = new GroupsImpl(clientObject.getGroups(), this);
        }
        return groups;
    }

    /** @return Resource collection API of GroupUsers. */
    public GroupUsers groupUsers() {
        if (this.groupUsers == null) {
            this.groupUsers = new GroupUsersImpl(clientObject.getGroupUsers(), this);
        }
        return groupUsers;
    }

    /** @return Resource collection API of IdentityProviders. */
    public IdentityProviders identityProviders() {
        if (this.identityProviders == null) {
            this.identityProviders = new IdentityProvidersImpl(clientObject.getIdentityProviders(), this);
        }
        return identityProviders;
    }

    /** @return Resource collection API of Issues. */
    public Issues issues() {
        if (this.issues == null) {
            this.issues = new IssuesImpl(clientObject.getIssues(), this);
        }
        return issues;
    }

    /** @return Resource collection API of Loggers. */
    public Loggers loggers() {
        if (this.loggers == null) {
            this.loggers = new LoggersImpl(clientObject.getLoggers(), this);
        }
        return loggers;
    }

    /** @return Resource collection API of NamedValues. */
    public NamedValues namedValues() {
        if (this.namedValues == null) {
            this.namedValues = new NamedValuesImpl(clientObject.getNamedValues(), this);
        }
        return namedValues;
    }

    /** @return Resource collection API of NetworkStatus. */
    public NetworkStatus networkStatus() {
        if (this.networkStatus == null) {
            this.networkStatus = new NetworkStatusImpl(clientObject.getNetworkStatus(), this);
        }
        return networkStatus;
    }

    /** @return Resource collection API of Notifications. */
    public Notifications notifications() {
        if (this.notifications == null) {
            this.notifications = new NotificationsImpl(clientObject.getNotifications(), this);
        }
        return notifications;
    }

    /** @return Resource collection API of NotificationRecipientUsers. */
    public NotificationRecipientUsers notificationRecipientUsers() {
        if (this.notificationRecipientUsers == null) {
            this.notificationRecipientUsers =
                new NotificationRecipientUsersImpl(clientObject.getNotificationRecipientUsers(), this);
        }
        return notificationRecipientUsers;
    }

    /** @return Resource collection API of NotificationRecipientEmails. */
    public NotificationRecipientEmails notificationRecipientEmails() {
        if (this.notificationRecipientEmails == null) {
            this.notificationRecipientEmails =
                new NotificationRecipientEmailsImpl(clientObject.getNotificationRecipientEmails(), this);
        }
        return notificationRecipientEmails;
    }

    /** @return Resource collection API of OpenIdConnectProviders. */
    public OpenIdConnectProviders openIdConnectProviders() {
        if (this.openIdConnectProviders == null) {
            this.openIdConnectProviders =
                new OpenIdConnectProvidersImpl(clientObject.getOpenIdConnectProviders(), this);
        }
        return openIdConnectProviders;
    }

    /** @return Resource collection API of OutboundNetworkDependenciesEndpoints. */
    public OutboundNetworkDependenciesEndpoints outboundNetworkDependenciesEndpoints() {
        if (this.outboundNetworkDependenciesEndpoints == null) {
            this.outboundNetworkDependenciesEndpoints =
                new OutboundNetworkDependenciesEndpointsImpl(
                    clientObject.getOutboundNetworkDependenciesEndpoints(), this);
        }
        return outboundNetworkDependenciesEndpoints;
    }

    /** @return Resource collection API of Policies. */
    public Policies policies() {
        if (this.policies == null) {
            this.policies = new PoliciesImpl(clientObject.getPolicies(), this);
        }
        return policies;
    }

    /** @return Resource collection API of PolicyDescriptions. */
    public PolicyDescriptions policyDescriptions() {
        if (this.policyDescriptions == null) {
            this.policyDescriptions = new PolicyDescriptionsImpl(clientObject.getPolicyDescriptions(), this);
        }
        return policyDescriptions;
    }

    /** @return Resource collection API of PortalRevisions. */
    public PortalRevisions portalRevisions() {
        if (this.portalRevisions == null) {
            this.portalRevisions = new PortalRevisionsImpl(clientObject.getPortalRevisions(), this);
        }
        return portalRevisions;
    }

    /** @return Resource collection API of PortalSettings. */
    public PortalSettings portalSettings() {
        if (this.portalSettings == null) {
            this.portalSettings = new PortalSettingsImpl(clientObject.getPortalSettings(), this);
        }
        return portalSettings;
    }

    /** @return Resource collection API of SignInSettings. */
    public SignInSettings signInSettings() {
        if (this.signInSettings == null) {
            this.signInSettings = new SignInSettingsImpl(clientObject.getSignInSettings(), this);
        }
        return signInSettings;
    }

    /** @return Resource collection API of SignUpSettings. */
    public SignUpSettings signUpSettings() {
        if (this.signUpSettings == null) {
            this.signUpSettings = new SignUpSettingsImpl(clientObject.getSignUpSettings(), this);
        }
        return signUpSettings;
    }

    /** @return Resource collection API of DelegationSettings. */
    public DelegationSettings delegationSettings() {
        if (this.delegationSettings == null) {
            this.delegationSettings = new DelegationSettingsImpl(clientObject.getDelegationSettings(), this);
        }
        return delegationSettings;
    }

    /** @return Resource collection API of PrivateEndpointConnections. */
    public PrivateEndpointConnections privateEndpointConnections() {
        if (this.privateEndpointConnections == null) {
            this.privateEndpointConnections =
                new PrivateEndpointConnectionsImpl(clientObject.getPrivateEndpointConnections(), this);
        }
        return privateEndpointConnections;
    }

    /** @return Resource collection API of Products. */
    public Products products() {
        if (this.products == null) {
            this.products = new ProductsImpl(clientObject.getProducts(), this);
        }
        return products;
    }

    /** @return Resource collection API of ProductApis. */
    public ProductApis productApis() {
        if (this.productApis == null) {
            this.productApis = new ProductApisImpl(clientObject.getProductApis(), this);
        }
        return productApis;
    }

    /** @return Resource collection API of ProductGroups. */
    public ProductGroups productGroups() {
        if (this.productGroups == null) {
            this.productGroups = new ProductGroupsImpl(clientObject.getProductGroups(), this);
        }
        return productGroups;
    }

    /** @return Resource collection API of ProductSubscriptions. */
    public ProductSubscriptions productSubscriptions() {
        if (this.productSubscriptions == null) {
            this.productSubscriptions = new ProductSubscriptionsImpl(clientObject.getProductSubscriptions(), this);
        }
        return productSubscriptions;
    }

    /** @return Resource collection API of ProductPolicies. */
    public ProductPolicies productPolicies() {
        if (this.productPolicies == null) {
            this.productPolicies = new ProductPoliciesImpl(clientObject.getProductPolicies(), this);
        }
        return productPolicies;
    }

    /** @return Resource collection API of QuotaByCounterKeys. */
    public QuotaByCounterKeys quotaByCounterKeys() {
        if (this.quotaByCounterKeys == null) {
            this.quotaByCounterKeys = new QuotaByCounterKeysImpl(clientObject.getQuotaByCounterKeys(), this);
        }
        return quotaByCounterKeys;
    }

    /** @return Resource collection API of QuotaByPeriodKeys. */
    public QuotaByPeriodKeys quotaByPeriodKeys() {
        if (this.quotaByPeriodKeys == null) {
            this.quotaByPeriodKeys = new QuotaByPeriodKeysImpl(clientObject.getQuotaByPeriodKeys(), this);
        }
        return quotaByPeriodKeys;
    }

    /** @return Resource collection API of Regions. */
    public Regions regions() {
        if (this.regions == null) {
            this.regions = new RegionsImpl(clientObject.getRegions(), this);
        }
        return regions;
    }

    /** @return Resource collection API of Reports. */
    public Reports reports() {
        if (this.reports == null) {
            this.reports = new ReportsImpl(clientObject.getReports(), this);
        }
        return reports;
    }

    /** @return Resource collection API of GlobalSchemas. */
    public GlobalSchemas globalSchemas() {
        if (this.globalSchemas == null) {
            this.globalSchemas = new GlobalSchemasImpl(clientObject.getGlobalSchemas(), this);
        }
        return globalSchemas;
    }

    /** @return Resource collection API of TenantSettings. */
    public TenantSettings tenantSettings() {
        if (this.tenantSettings == null) {
            this.tenantSettings = new TenantSettingsImpl(clientObject.getTenantSettings(), this);
        }
        return tenantSettings;
    }

    /** @return Resource collection API of ApiManagementSkus. */
    public ApiManagementSkus apiManagementSkus() {
        if (this.apiManagementSkus == null) {
            this.apiManagementSkus = new ApiManagementSkusImpl(clientObject.getApiManagementSkus(), this);
        }
        return apiManagementSkus;
    }

    /** @return Resource collection API of Subscriptions. */
    public Subscriptions subscriptions() {
        if (this.subscriptions == null) {
            this.subscriptions = new SubscriptionsImpl(clientObject.getSubscriptions(), this);
        }
        return subscriptions;
    }

    /** @return Resource collection API of TagResources. */
    public TagResources tagResources() {
        if (this.tagResources == null) {
            this.tagResources = new TagResourcesImpl(clientObject.getTagResources(), this);
        }
        return tagResources;
    }

    /** @return Resource collection API of TenantAccess. */
    public TenantAccess tenantAccess() {
        if (this.tenantAccess == null) {
            this.tenantAccess = new TenantAccessImpl(clientObject.getTenantAccess(), this);
        }
        return tenantAccess;
    }

    /** @return Resource collection API of TenantAccessGits. */
    public TenantAccessGits tenantAccessGits() {
        if (this.tenantAccessGits == null) {
            this.tenantAccessGits = new TenantAccessGitsImpl(clientObject.getTenantAccessGits(), this);
        }
        return tenantAccessGits;
    }

    /** @return Resource collection API of TenantConfigurations. */
    public TenantConfigurations tenantConfigurations() {
        if (this.tenantConfigurations == null) {
            this.tenantConfigurations = new TenantConfigurationsImpl(clientObject.getTenantConfigurations(), this);
        }
        return tenantConfigurations;
    }

    /** @return Resource collection API of Users. */
    public Users users() {
        if (this.users == null) {
            this.users = new UsersImpl(clientObject.getUsers(), this);
        }
        return users;
    }

    /** @return Resource collection API of UserGroups. */
    public UserGroups userGroups() {
        if (this.userGroups == null) {
            this.userGroups = new UserGroupsImpl(clientObject.getUserGroups(), this);
        }
        return userGroups;
    }

    /** @return Resource collection API of UserSubscriptions. */
    public UserSubscriptions userSubscriptions() {
        if (this.userSubscriptions == null) {
            this.userSubscriptions = new UserSubscriptionsImpl(clientObject.getUserSubscriptions(), this);
        }
        return userSubscriptions;
    }

    /** @return Resource collection API of UserIdentities. */
    public UserIdentities userIdentities() {
        if (this.userIdentities == null) {
            this.userIdentities = new UserIdentitiesImpl(clientObject.getUserIdentities(), this);
        }
        return userIdentities;
    }

    /** @return Resource collection API of UserConfirmationPasswords. */
    public UserConfirmationPasswords userConfirmationPasswords() {
        if (this.userConfirmationPasswords == null) {
            this.userConfirmationPasswords =
                new UserConfirmationPasswordsImpl(clientObject.getUserConfirmationPasswords(), this);
        }
        return userConfirmationPasswords;
    }

    /**
     * @return Wrapped service client ApiManagementClient providing direct access to the underlying auto-generated API
     *     implementation, based on Azure REST API.
     */
    public ApiManagementClient serviceClient() {
        return this.clientObject;
    }
}
