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

package com.azure.resourcemanager.automation;

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.AddHeadersFromContextPolicy;
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.RetryOptions;
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.automation.fluent.AutomationClient;
import com.azure.resourcemanager.automation.implementation.ActivitiesImpl;
import com.azure.resourcemanager.automation.implementation.AgentRegistrationInformationsImpl;
import com.azure.resourcemanager.automation.implementation.AutomationAccountsImpl;
import com.azure.resourcemanager.automation.implementation.AutomationClientBuilder;
import com.azure.resourcemanager.automation.implementation.CertificatesImpl;
import com.azure.resourcemanager.automation.implementation.ConnectionTypesImpl;
import com.azure.resourcemanager.automation.implementation.ConnectionsImpl;
import com.azure.resourcemanager.automation.implementation.CredentialsImpl;
import com.azure.resourcemanager.automation.implementation.DeletedAutomationAccountsImpl;
import com.azure.resourcemanager.automation.implementation.DscCompilationJobStreamsImpl;
import com.azure.resourcemanager.automation.implementation.DscCompilationJobsImpl;
import com.azure.resourcemanager.automation.implementation.DscConfigurationsImpl;
import com.azure.resourcemanager.automation.implementation.DscNodeConfigurationsImpl;
import com.azure.resourcemanager.automation.implementation.DscNodesImpl;
import com.azure.resourcemanager.automation.implementation.FieldsImpl;
import com.azure.resourcemanager.automation.implementation.HybridRunbookWorkerGroupsImpl;
import com.azure.resourcemanager.automation.implementation.HybridRunbookWorkersImpl;
import com.azure.resourcemanager.automation.implementation.JobSchedulesImpl;
import com.azure.resourcemanager.automation.implementation.JobStreamsImpl;
import com.azure.resourcemanager.automation.implementation.JobsImpl;
import com.azure.resourcemanager.automation.implementation.KeysImpl;
import com.azure.resourcemanager.automation.implementation.LinkedWorkspacesImpl;
import com.azure.resourcemanager.automation.implementation.ModulesImpl;
import com.azure.resourcemanager.automation.implementation.NodeCountInformationsImpl;
import com.azure.resourcemanager.automation.implementation.NodeReportsImpl;
import com.azure.resourcemanager.automation.implementation.ObjectDataTypesImpl;
import com.azure.resourcemanager.automation.implementation.OperationsImpl;
import com.azure.resourcemanager.automation.implementation.PrivateEndpointConnectionsImpl;
import com.azure.resourcemanager.automation.implementation.PrivateLinkResourcesImpl;
import com.azure.resourcemanager.automation.implementation.Python2PackagesImpl;
import com.azure.resourcemanager.automation.implementation.ResourceProvidersImpl;
import com.azure.resourcemanager.automation.implementation.RunbookDraftsImpl;
import com.azure.resourcemanager.automation.implementation.RunbooksImpl;
import com.azure.resourcemanager.automation.implementation.SchedulesImpl;
import com.azure.resourcemanager.automation.implementation.SoftwareUpdateConfigurationMachineRunsImpl;
import com.azure.resourcemanager.automation.implementation.SoftwareUpdateConfigurationRunsImpl;
import com.azure.resourcemanager.automation.implementation.SoftwareUpdateConfigurationsImpl;
import com.azure.resourcemanager.automation.implementation.SourceControlSyncJobStreamsImpl;
import com.azure.resourcemanager.automation.implementation.SourceControlSyncJobsImpl;
import com.azure.resourcemanager.automation.implementation.SourceControlsImpl;
import com.azure.resourcemanager.automation.implementation.StatisticsOperationsImpl;
import com.azure.resourcemanager.automation.implementation.TestJobStreamsImpl;
import com.azure.resourcemanager.automation.implementation.TestJobsImpl;
import com.azure.resourcemanager.automation.implementation.UsagesImpl;
import com.azure.resourcemanager.automation.implementation.VariablesImpl;
import com.azure.resourcemanager.automation.implementation.WatchersImpl;
import com.azure.resourcemanager.automation.implementation.WebhooksImpl;
import com.azure.resourcemanager.automation.models.Activities;
import com.azure.resourcemanager.automation.models.AgentRegistrationInformations;
import com.azure.resourcemanager.automation.models.AutomationAccounts;
import com.azure.resourcemanager.automation.models.Certificates;
import com.azure.resourcemanager.automation.models.ConnectionTypes;
import com.azure.resourcemanager.automation.models.Connections;
import com.azure.resourcemanager.automation.models.Credentials;
import com.azure.resourcemanager.automation.models.DeletedAutomationAccounts;
import com.azure.resourcemanager.automation.models.DscCompilationJobStreams;
import com.azure.resourcemanager.automation.models.DscCompilationJobs;
import com.azure.resourcemanager.automation.models.DscConfigurations;
import com.azure.resourcemanager.automation.models.DscNodeConfigurations;
import com.azure.resourcemanager.automation.models.DscNodes;
import com.azure.resourcemanager.automation.models.Fields;
import com.azure.resourcemanager.automation.models.HybridRunbookWorkerGroups;
import com.azure.resourcemanager.automation.models.HybridRunbookWorkers;
import com.azure.resourcemanager.automation.models.JobSchedules;
import com.azure.resourcemanager.automation.models.JobStreams;
import com.azure.resourcemanager.automation.models.Jobs;
import com.azure.resourcemanager.automation.models.Keys;
import com.azure.resourcemanager.automation.models.LinkedWorkspaces;
import com.azure.resourcemanager.automation.models.Modules;
import com.azure.resourcemanager.automation.models.NodeCountInformations;
import com.azure.resourcemanager.automation.models.NodeReports;
import com.azure.resourcemanager.automation.models.ObjectDataTypes;
import com.azure.resourcemanager.automation.models.Operations;
import com.azure.resourcemanager.automation.models.PrivateEndpointConnections;
import com.azure.resourcemanager.automation.models.PrivateLinkResources;
import com.azure.resourcemanager.automation.models.Python2Packages;
import com.azure.resourcemanager.automation.models.ResourceProviders;
import com.azure.resourcemanager.automation.models.RunbookDrafts;
import com.azure.resourcemanager.automation.models.Runbooks;
import com.azure.resourcemanager.automation.models.Schedules;
import com.azure.resourcemanager.automation.models.SoftwareUpdateConfigurationMachineRuns;
import com.azure.resourcemanager.automation.models.SoftwareUpdateConfigurationRuns;
import com.azure.resourcemanager.automation.models.SoftwareUpdateConfigurations;
import com.azure.resourcemanager.automation.models.SourceControlSyncJobStreams;
import com.azure.resourcemanager.automation.models.SourceControlSyncJobs;
import com.azure.resourcemanager.automation.models.SourceControls;
import com.azure.resourcemanager.automation.models.StatisticsOperations;
import com.azure.resourcemanager.automation.models.TestJobStreams;
import com.azure.resourcemanager.automation.models.TestJobs;
import com.azure.resourcemanager.automation.models.Usages;
import com.azure.resourcemanager.automation.models.Variables;
import com.azure.resourcemanager.automation.models.Watchers;
import com.azure.resourcemanager.automation.models.Webhooks;
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 AutomationManager. Automation Client. */
public final class AutomationManager {
    private PrivateEndpointConnections privateEndpointConnections;

    private PrivateLinkResources privateLinkResources;

    private Python2Packages python2Packages;

    private AgentRegistrationInformations agentRegistrationInformations;

    private DscNodes dscNodes;

    private NodeReports nodeReports;

    private DscNodeConfigurations dscNodeConfigurations;

    private DscCompilationJobs dscCompilationJobs;

    private DscCompilationJobStreams dscCompilationJobStreams;

    private NodeCountInformations nodeCountInformations;

    private SourceControls sourceControls;

    private SourceControlSyncJobs sourceControlSyncJobs;

    private SourceControlSyncJobStreams sourceControlSyncJobStreams;

    private AutomationAccounts automationAccounts;

    private StatisticsOperations statisticsOperations;

    private Usages usages;

    private Keys keys;

    private Certificates certificates;

    private Connections connections;

    private ConnectionTypes connectionTypes;

    private Credentials credentials;

    private JobSchedules jobSchedules;

    private LinkedWorkspaces linkedWorkspaces;

    private Activities activities;

    private Modules modules;

    private ObjectDataTypes objectDataTypes;

    private Fields fields;

    private Schedules schedules;

    private Variables variables;

    private Watchers watchers;

    private DscConfigurations dscConfigurations;

    private Jobs jobs;

    private JobStreams jobStreams;

    private Operations operations;

    private ResourceProviders resourceProviders;

    private SoftwareUpdateConfigurations softwareUpdateConfigurations;

    private SoftwareUpdateConfigurationRuns softwareUpdateConfigurationRuns;

    private SoftwareUpdateConfigurationMachineRuns softwareUpdateConfigurationMachineRuns;

    private RunbookDrafts runbookDrafts;

    private Runbooks runbooks;

    private TestJobStreams testJobStreams;

    private TestJobs testJobs;

    private Webhooks webhooks;

    private HybridRunbookWorkers hybridRunbookWorkers;

    private DeletedAutomationAccounts deletedAutomationAccounts;

    private HybridRunbookWorkerGroups hybridRunbookWorkerGroups;

    private final AutomationClient clientObject;

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

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

    /**
     * Creates an instance of Automation service API entry point.
     *
     * @param httpPipeline the {@link HttpPipeline} configured with Azure authentication credential.
     * @param profile the Azure profile for client.
     * @return the Automation service API instance.
     */
    public static AutomationManager authenticate(HttpPipeline httpPipeline, AzureProfile profile) {
        Objects.requireNonNull(httpPipeline, "'httpPipeline' cannot be null.");
        Objects.requireNonNull(profile, "'profile' cannot be null.");
        return new AutomationManager(httpPipeline, profile, null);
    }

    /**
     * Gets a Configurable instance that can be used to create AutomationManager with optional configuration.
     *
     * @return the Configurable instance allowing configurations.
     */
    public static Configurable configure() {
        return new AutomationManager.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 RetryOptions retryOptions;
        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 retry options for the HTTP pipeline retry policy.
         *
         * <p>This setting has no effect, if retry policy is set via {@link #withRetryPolicy(RetryPolicy)}.
         *
         * @param retryOptions the retry options for the HTTP pipeline retry policy.
         * @return the configurable object itself.
         */
        public Configurable withRetryOptions(RetryOptions retryOptions) {
            this.retryOptions = Objects.requireNonNull(retryOptions, "'retryOptions' 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 Automation service API entry point.
         *
         * @param credential the credential to use.
         * @param profile the Azure profile for client.
         * @return the Automation service API instance.
         */
        public AutomationManager 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.automation")
                .append("/")
                .append("1.0.0-beta.2");
            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) {
                if (retryOptions != null) {
                    retryPolicy = new RetryPolicy(retryOptions);
                } else {
                    retryPolicy = new RetryPolicy("Retry-After", ChronoUnit.SECONDS);
                }
            }
            List<HttpPipelinePolicy> policies = new ArrayList<>();
            policies.add(new UserAgentPolicy(userAgentBuilder.toString()));
            policies.add(new AddHeadersFromContextPolicy());
            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 AutomationManager(httpPipeline, profile, defaultPollInterval);
        }
    }

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

    /**
     * Gets the resource collection API of PrivateLinkResources.
     *
     * @return Resource collection API of PrivateLinkResources.
     */
    public PrivateLinkResources privateLinkResources() {
        if (this.privateLinkResources == null) {
            this.privateLinkResources = new PrivateLinkResourcesImpl(clientObject.getPrivateLinkResources(), this);
        }
        return privateLinkResources;
    }

    /**
     * Gets the resource collection API of Python2Packages. It manages Module.
     *
     * @return Resource collection API of Python2Packages.
     */
    public Python2Packages python2Packages() {
        if (this.python2Packages == null) {
            this.python2Packages = new Python2PackagesImpl(clientObject.getPython2Packages(), this);
        }
        return python2Packages;
    }

    /**
     * Gets the resource collection API of AgentRegistrationInformations.
     *
     * @return Resource collection API of AgentRegistrationInformations.
     */
    public AgentRegistrationInformations agentRegistrationInformations() {
        if (this.agentRegistrationInformations == null) {
            this.agentRegistrationInformations =
                new AgentRegistrationInformationsImpl(clientObject.getAgentRegistrationInformations(), this);
        }
        return agentRegistrationInformations;
    }

    /**
     * Gets the resource collection API of DscNodes.
     *
     * @return Resource collection API of DscNodes.
     */
    public DscNodes dscNodes() {
        if (this.dscNodes == null) {
            this.dscNodes = new DscNodesImpl(clientObject.getDscNodes(), this);
        }
        return dscNodes;
    }

    /**
     * Gets the resource collection API of NodeReports.
     *
     * @return Resource collection API of NodeReports.
     */
    public NodeReports nodeReports() {
        if (this.nodeReports == null) {
            this.nodeReports = new NodeReportsImpl(clientObject.getNodeReports(), this);
        }
        return nodeReports;
    }

    /**
     * Gets the resource collection API of DscNodeConfigurations. It manages DscNodeConfiguration.
     *
     * @return Resource collection API of DscNodeConfigurations.
     */
    public DscNodeConfigurations dscNodeConfigurations() {
        if (this.dscNodeConfigurations == null) {
            this.dscNodeConfigurations = new DscNodeConfigurationsImpl(clientObject.getDscNodeConfigurations(), this);
        }
        return dscNodeConfigurations;
    }

    /**
     * Gets the resource collection API of DscCompilationJobs. It manages DscCompilationJob.
     *
     * @return Resource collection API of DscCompilationJobs.
     */
    public DscCompilationJobs dscCompilationJobs() {
        if (this.dscCompilationJobs == null) {
            this.dscCompilationJobs = new DscCompilationJobsImpl(clientObject.getDscCompilationJobs(), this);
        }
        return dscCompilationJobs;
    }

    /**
     * Gets the resource collection API of DscCompilationJobStreams.
     *
     * @return Resource collection API of DscCompilationJobStreams.
     */
    public DscCompilationJobStreams dscCompilationJobStreams() {
        if (this.dscCompilationJobStreams == null) {
            this.dscCompilationJobStreams =
                new DscCompilationJobStreamsImpl(clientObject.getDscCompilationJobStreams(), this);
        }
        return dscCompilationJobStreams;
    }

    /**
     * Gets the resource collection API of NodeCountInformations.
     *
     * @return Resource collection API of NodeCountInformations.
     */
    public NodeCountInformations nodeCountInformations() {
        if (this.nodeCountInformations == null) {
            this.nodeCountInformations = new NodeCountInformationsImpl(clientObject.getNodeCountInformations(), this);
        }
        return nodeCountInformations;
    }

    /**
     * Gets the resource collection API of SourceControls. It manages SourceControl.
     *
     * @return Resource collection API of SourceControls.
     */
    public SourceControls sourceControls() {
        if (this.sourceControls == null) {
            this.sourceControls = new SourceControlsImpl(clientObject.getSourceControls(), this);
        }
        return sourceControls;
    }

    /**
     * Gets the resource collection API of SourceControlSyncJobs. It manages SourceControlSyncJob.
     *
     * @return Resource collection API of SourceControlSyncJobs.
     */
    public SourceControlSyncJobs sourceControlSyncJobs() {
        if (this.sourceControlSyncJobs == null) {
            this.sourceControlSyncJobs = new SourceControlSyncJobsImpl(clientObject.getSourceControlSyncJobs(), this);
        }
        return sourceControlSyncJobs;
    }

    /**
     * Gets the resource collection API of SourceControlSyncJobStreams.
     *
     * @return Resource collection API of SourceControlSyncJobStreams.
     */
    public SourceControlSyncJobStreams sourceControlSyncJobStreams() {
        if (this.sourceControlSyncJobStreams == null) {
            this.sourceControlSyncJobStreams =
                new SourceControlSyncJobStreamsImpl(clientObject.getSourceControlSyncJobStreams(), this);
        }
        return sourceControlSyncJobStreams;
    }

    /**
     * Gets the resource collection API of AutomationAccounts. It manages AutomationAccount.
     *
     * @return Resource collection API of AutomationAccounts.
     */
    public AutomationAccounts automationAccounts() {
        if (this.automationAccounts == null) {
            this.automationAccounts = new AutomationAccountsImpl(clientObject.getAutomationAccounts(), this);
        }
        return automationAccounts;
    }

    /**
     * Gets the resource collection API of StatisticsOperations.
     *
     * @return Resource collection API of StatisticsOperations.
     */
    public StatisticsOperations statisticsOperations() {
        if (this.statisticsOperations == null) {
            this.statisticsOperations = new StatisticsOperationsImpl(clientObject.getStatisticsOperations(), this);
        }
        return statisticsOperations;
    }

    /**
     * Gets the resource collection API of Usages.
     *
     * @return Resource collection API of Usages.
     */
    public Usages usages() {
        if (this.usages == null) {
            this.usages = new UsagesImpl(clientObject.getUsages(), this);
        }
        return usages;
    }

    /**
     * Gets the resource collection API of Keys.
     *
     * @return Resource collection API of Keys.
     */
    public Keys keys() {
        if (this.keys == null) {
            this.keys = new KeysImpl(clientObject.getKeys(), this);
        }
        return keys;
    }

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

    /**
     * Gets the resource collection API of Connections. It manages Connection.
     *
     * @return Resource collection API of Connections.
     */
    public Connections connections() {
        if (this.connections == null) {
            this.connections = new ConnectionsImpl(clientObject.getConnections(), this);
        }
        return connections;
    }

    /**
     * Gets the resource collection API of ConnectionTypes. It manages ConnectionType.
     *
     * @return Resource collection API of ConnectionTypes.
     */
    public ConnectionTypes connectionTypes() {
        if (this.connectionTypes == null) {
            this.connectionTypes = new ConnectionTypesImpl(clientObject.getConnectionTypes(), this);
        }
        return connectionTypes;
    }

    /**
     * Gets the resource collection API of Credentials. It manages Credential.
     *
     * @return Resource collection API of Credentials.
     */
    public Credentials credentials() {
        if (this.credentials == null) {
            this.credentials = new CredentialsImpl(clientObject.getCredentials(), this);
        }
        return credentials;
    }

    /**
     * Gets the resource collection API of JobSchedules. It manages JobSchedule.
     *
     * @return Resource collection API of JobSchedules.
     */
    public JobSchedules jobSchedules() {
        if (this.jobSchedules == null) {
            this.jobSchedules = new JobSchedulesImpl(clientObject.getJobSchedules(), this);
        }
        return jobSchedules;
    }

    /**
     * Gets the resource collection API of LinkedWorkspaces.
     *
     * @return Resource collection API of LinkedWorkspaces.
     */
    public LinkedWorkspaces linkedWorkspaces() {
        if (this.linkedWorkspaces == null) {
            this.linkedWorkspaces = new LinkedWorkspacesImpl(clientObject.getLinkedWorkspaces(), this);
        }
        return linkedWorkspaces;
    }

    /**
     * Gets the resource collection API of Activities.
     *
     * @return Resource collection API of Activities.
     */
    public Activities activities() {
        if (this.activities == null) {
            this.activities = new ActivitiesImpl(clientObject.getActivities(), this);
        }
        return activities;
    }

    /**
     * Gets the resource collection API of Modules.
     *
     * @return Resource collection API of Modules.
     */
    public Modules modules() {
        if (this.modules == null) {
            this.modules = new ModulesImpl(clientObject.getModules(), this);
        }
        return modules;
    }

    /**
     * Gets the resource collection API of ObjectDataTypes.
     *
     * @return Resource collection API of ObjectDataTypes.
     */
    public ObjectDataTypes objectDataTypes() {
        if (this.objectDataTypes == null) {
            this.objectDataTypes = new ObjectDataTypesImpl(clientObject.getObjectDataTypes(), this);
        }
        return objectDataTypes;
    }

    /**
     * Gets the resource collection API of Fields.
     *
     * @return Resource collection API of Fields.
     */
    public Fields fields() {
        if (this.fields == null) {
            this.fields = new FieldsImpl(clientObject.getFields(), this);
        }
        return fields;
    }

    /**
     * Gets the resource collection API of Schedules. It manages Schedule.
     *
     * @return Resource collection API of Schedules.
     */
    public Schedules schedules() {
        if (this.schedules == null) {
            this.schedules = new SchedulesImpl(clientObject.getSchedules(), this);
        }
        return schedules;
    }

    /**
     * Gets the resource collection API of Variables. It manages Variable.
     *
     * @return Resource collection API of Variables.
     */
    public Variables variables() {
        if (this.variables == null) {
            this.variables = new VariablesImpl(clientObject.getVariables(), this);
        }
        return variables;
    }

    /**
     * Gets the resource collection API of Watchers. It manages Watcher.
     *
     * @return Resource collection API of Watchers.
     */
    public Watchers watchers() {
        if (this.watchers == null) {
            this.watchers = new WatchersImpl(clientObject.getWatchers(), this);
        }
        return watchers;
    }

    /**
     * Gets the resource collection API of DscConfigurations. It manages DscConfiguration.
     *
     * @return Resource collection API of DscConfigurations.
     */
    public DscConfigurations dscConfigurations() {
        if (this.dscConfigurations == null) {
            this.dscConfigurations = new DscConfigurationsImpl(clientObject.getDscConfigurations(), this);
        }
        return dscConfigurations;
    }

    /**
     * Gets the resource collection API of Jobs. It manages Job.
     *
     * @return Resource collection API of Jobs.
     */
    public Jobs jobs() {
        if (this.jobs == null) {
            this.jobs = new JobsImpl(clientObject.getJobs(), this);
        }
        return jobs;
    }

    /**
     * Gets the resource collection API of JobStreams.
     *
     * @return Resource collection API of JobStreams.
     */
    public JobStreams jobStreams() {
        if (this.jobStreams == null) {
            this.jobStreams = new JobStreamsImpl(clientObject.getJobStreams(), this);
        }
        return jobStreams;
    }

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

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

    /**
     * Gets the resource collection API of SoftwareUpdateConfigurations. It manages SoftwareUpdateConfiguration.
     *
     * @return Resource collection API of SoftwareUpdateConfigurations.
     */
    public SoftwareUpdateConfigurations softwareUpdateConfigurations() {
        if (this.softwareUpdateConfigurations == null) {
            this.softwareUpdateConfigurations =
                new SoftwareUpdateConfigurationsImpl(clientObject.getSoftwareUpdateConfigurations(), this);
        }
        return softwareUpdateConfigurations;
    }

    /**
     * Gets the resource collection API of SoftwareUpdateConfigurationRuns.
     *
     * @return Resource collection API of SoftwareUpdateConfigurationRuns.
     */
    public SoftwareUpdateConfigurationRuns softwareUpdateConfigurationRuns() {
        if (this.softwareUpdateConfigurationRuns == null) {
            this.softwareUpdateConfigurationRuns =
                new SoftwareUpdateConfigurationRunsImpl(clientObject.getSoftwareUpdateConfigurationRuns(), this);
        }
        return softwareUpdateConfigurationRuns;
    }

    /**
     * Gets the resource collection API of SoftwareUpdateConfigurationMachineRuns.
     *
     * @return Resource collection API of SoftwareUpdateConfigurationMachineRuns.
     */
    public SoftwareUpdateConfigurationMachineRuns softwareUpdateConfigurationMachineRuns() {
        if (this.softwareUpdateConfigurationMachineRuns == null) {
            this.softwareUpdateConfigurationMachineRuns =
                new SoftwareUpdateConfigurationMachineRunsImpl(
                    clientObject.getSoftwareUpdateConfigurationMachineRuns(), this);
        }
        return softwareUpdateConfigurationMachineRuns;
    }

    /**
     * Gets the resource collection API of RunbookDrafts.
     *
     * @return Resource collection API of RunbookDrafts.
     */
    public RunbookDrafts runbookDrafts() {
        if (this.runbookDrafts == null) {
            this.runbookDrafts = new RunbookDraftsImpl(clientObject.getRunbookDrafts(), this);
        }
        return runbookDrafts;
    }

    /**
     * Gets the resource collection API of Runbooks. It manages Runbook.
     *
     * @return Resource collection API of Runbooks.
     */
    public Runbooks runbooks() {
        if (this.runbooks == null) {
            this.runbooks = new RunbooksImpl(clientObject.getRunbooks(), this);
        }
        return runbooks;
    }

    /**
     * Gets the resource collection API of TestJobStreams.
     *
     * @return Resource collection API of TestJobStreams.
     */
    public TestJobStreams testJobStreams() {
        if (this.testJobStreams == null) {
            this.testJobStreams = new TestJobStreamsImpl(clientObject.getTestJobStreams(), this);
        }
        return testJobStreams;
    }

    /**
     * Gets the resource collection API of TestJobs.
     *
     * @return Resource collection API of TestJobs.
     */
    public TestJobs testJobs() {
        if (this.testJobs == null) {
            this.testJobs = new TestJobsImpl(clientObject.getTestJobs(), this);
        }
        return testJobs;
    }

    /**
     * Gets the resource collection API of Webhooks. It manages Webhook.
     *
     * @return Resource collection API of Webhooks.
     */
    public Webhooks webhooks() {
        if (this.webhooks == null) {
            this.webhooks = new WebhooksImpl(clientObject.getWebhooks(), this);
        }
        return webhooks;
    }

    /**
     * Gets the resource collection API of HybridRunbookWorkers. It manages HybridRunbookWorker.
     *
     * @return Resource collection API of HybridRunbookWorkers.
     */
    public HybridRunbookWorkers hybridRunbookWorkers() {
        if (this.hybridRunbookWorkers == null) {
            this.hybridRunbookWorkers = new HybridRunbookWorkersImpl(clientObject.getHybridRunbookWorkers(), this);
        }
        return hybridRunbookWorkers;
    }

    /**
     * Gets the resource collection API of DeletedAutomationAccounts.
     *
     * @return Resource collection API of DeletedAutomationAccounts.
     */
    public DeletedAutomationAccounts deletedAutomationAccounts() {
        if (this.deletedAutomationAccounts == null) {
            this.deletedAutomationAccounts =
                new DeletedAutomationAccountsImpl(clientObject.getDeletedAutomationAccounts(), this);
        }
        return deletedAutomationAccounts;
    }

    /**
     * Gets the resource collection API of HybridRunbookWorkerGroups. It manages HybridRunbookWorkerGroup.
     *
     * @return Resource collection API of HybridRunbookWorkerGroups.
     */
    public HybridRunbookWorkerGroups hybridRunbookWorkerGroups() {
        if (this.hybridRunbookWorkerGroups == null) {
            this.hybridRunbookWorkerGroups =
                new HybridRunbookWorkerGroupsImpl(clientObject.getHybridRunbookWorkerGroups(), this);
        }
        return hybridRunbookWorkerGroups;
    }

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