<?php
/*
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * GENERATED CODE WARNING
 * Generated by gapic-generator-php from the file
 * https://github.com/googleapis/googleapis/blob/master/google/analytics/admin/v1beta/analytics_admin.proto
 * Updates to the above are reflected here through a refresh process.
 *
 * @experimental
 */

namespace Google\Analytics\Admin\V1beta\Gapic;

use Google\Analytics\Admin\V1beta\Account;
use Google\Analytics\Admin\V1beta\AcknowledgeUserDataCollectionRequest;
use Google\Analytics\Admin\V1beta\AcknowledgeUserDataCollectionResponse;
use Google\Analytics\Admin\V1beta\ArchiveCustomDimensionRequest;
use Google\Analytics\Admin\V1beta\ArchiveCustomMetricRequest;
use Google\Analytics\Admin\V1beta\ConversionEvent;
use Google\Analytics\Admin\V1beta\CreateConversionEventRequest;
use Google\Analytics\Admin\V1beta\CreateCustomDimensionRequest;
use Google\Analytics\Admin\V1beta\CreateCustomMetricRequest;
use Google\Analytics\Admin\V1beta\CreateDataStreamRequest;
use Google\Analytics\Admin\V1beta\CreateFirebaseLinkRequest;
use Google\Analytics\Admin\V1beta\CreateGoogleAdsLinkRequest;
use Google\Analytics\Admin\V1beta\CreateMeasurementProtocolSecretRequest;
use Google\Analytics\Admin\V1beta\CreatePropertyRequest;
use Google\Analytics\Admin\V1beta\CustomDimension;
use Google\Analytics\Admin\V1beta\CustomMetric;
use Google\Analytics\Admin\V1beta\DataRetentionSettings;
use Google\Analytics\Admin\V1beta\DataSharingSettings;
use Google\Analytics\Admin\V1beta\DataStream;
use Google\Analytics\Admin\V1beta\DeleteAccountRequest;
use Google\Analytics\Admin\V1beta\DeleteConversionEventRequest;
use Google\Analytics\Admin\V1beta\DeleteDataStreamRequest;
use Google\Analytics\Admin\V1beta\DeleteFirebaseLinkRequest;
use Google\Analytics\Admin\V1beta\DeleteGoogleAdsLinkRequest;
use Google\Analytics\Admin\V1beta\DeleteMeasurementProtocolSecretRequest;
use Google\Analytics\Admin\V1beta\DeletePropertyRequest;
use Google\Analytics\Admin\V1beta\FirebaseLink;
use Google\Analytics\Admin\V1beta\GetAccountRequest;
use Google\Analytics\Admin\V1beta\GetConversionEventRequest;
use Google\Analytics\Admin\V1beta\GetCustomDimensionRequest;
use Google\Analytics\Admin\V1beta\GetCustomMetricRequest;
use Google\Analytics\Admin\V1beta\GetDataRetentionSettingsRequest;
use Google\Analytics\Admin\V1beta\GetDataSharingSettingsRequest;
use Google\Analytics\Admin\V1beta\GetDataStreamRequest;
use Google\Analytics\Admin\V1beta\GetMeasurementProtocolSecretRequest;
use Google\Analytics\Admin\V1beta\GetPropertyRequest;
use Google\Analytics\Admin\V1beta\GoogleAdsLink;
use Google\Analytics\Admin\V1beta\ListAccountSummariesRequest;
use Google\Analytics\Admin\V1beta\ListAccountSummariesResponse;
use Google\Analytics\Admin\V1beta\ListAccountsRequest;
use Google\Analytics\Admin\V1beta\ListAccountsResponse;
use Google\Analytics\Admin\V1beta\ListConversionEventsRequest;
use Google\Analytics\Admin\V1beta\ListConversionEventsResponse;
use Google\Analytics\Admin\V1beta\ListCustomDimensionsRequest;
use Google\Analytics\Admin\V1beta\ListCustomDimensionsResponse;
use Google\Analytics\Admin\V1beta\ListCustomMetricsRequest;
use Google\Analytics\Admin\V1beta\ListCustomMetricsResponse;
use Google\Analytics\Admin\V1beta\ListDataStreamsRequest;
use Google\Analytics\Admin\V1beta\ListDataStreamsResponse;
use Google\Analytics\Admin\V1beta\ListFirebaseLinksRequest;
use Google\Analytics\Admin\V1beta\ListFirebaseLinksResponse;
use Google\Analytics\Admin\V1beta\ListGoogleAdsLinksRequest;
use Google\Analytics\Admin\V1beta\ListGoogleAdsLinksResponse;
use Google\Analytics\Admin\V1beta\ListMeasurementProtocolSecretsRequest;
use Google\Analytics\Admin\V1beta\ListMeasurementProtocolSecretsResponse;
use Google\Analytics\Admin\V1beta\ListPropertiesRequest;
use Google\Analytics\Admin\V1beta\ListPropertiesResponse;
use Google\Analytics\Admin\V1beta\MeasurementProtocolSecret;
use Google\Analytics\Admin\V1beta\Property;
use Google\Analytics\Admin\V1beta\ProvisionAccountTicketRequest;
use Google\Analytics\Admin\V1beta\ProvisionAccountTicketResponse;
use Google\Analytics\Admin\V1beta\SearchChangeHistoryEventsRequest;
use Google\Analytics\Admin\V1beta\SearchChangeHistoryEventsResponse;
use Google\Analytics\Admin\V1beta\UpdateAccountRequest;
use Google\Analytics\Admin\V1beta\UpdateCustomDimensionRequest;
use Google\Analytics\Admin\V1beta\UpdateCustomMetricRequest;
use Google\Analytics\Admin\V1beta\UpdateDataRetentionSettingsRequest;
use Google\Analytics\Admin\V1beta\UpdateDataStreamRequest;
use Google\Analytics\Admin\V1beta\UpdateGoogleAdsLinkRequest;
use Google\Analytics\Admin\V1beta\UpdateMeasurementProtocolSecretRequest;
use Google\Analytics\Admin\V1beta\UpdatePropertyRequest;
use Google\ApiCore\ApiException;
use Google\ApiCore\CredentialsWrapper;
use Google\ApiCore\GapicClientTrait;
use Google\ApiCore\PathTemplate;
use Google\ApiCore\RequestParamsHeaderDescriptor;
use Google\ApiCore\RetrySettings;
use Google\ApiCore\Transport\TransportInterface;
use Google\ApiCore\ValidationException;
use Google\Auth\FetchAuthTokenInterface;
use Google\Protobuf\FieldMask;
use Google\Protobuf\GPBEmpty;
use Google\Protobuf\Timestamp;

/**
 * Service Description: Service Interface for the Analytics Admin API (GA4).
 *
 * This class provides the ability to make remote calls to the backing service through method
 * calls that map to API methods. Sample code to get started:
 *
 * ```
 * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
 * try {
 *     $formattedProperty = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
 *     $acknowledgement = 'acknowledgement';
 *     $response = $analyticsAdminServiceClient->acknowledgeUserDataCollection($formattedProperty, $acknowledgement);
 * } finally {
 *     $analyticsAdminServiceClient->close();
 * }
 * ```
 *
 * Many parameters require resource names to be formatted in a particular way. To
 * assist with these names, this class includes a format method for each type of
 * name, and additionally a parseName method to extract the individual identifiers
 * contained within formatted names that are returned by the API.
 *
 * @experimental
 */
class AnalyticsAdminServiceGapicClient
{
    use GapicClientTrait;

    /** The name of the service. */
    const SERVICE_NAME = 'google.analytics.admin.v1beta.AnalyticsAdminService';

    /** The default address of the service. */
    const SERVICE_ADDRESS = 'analyticsadmin.googleapis.com';

    /** The default port of the service. */
    const DEFAULT_SERVICE_PORT = 443;

    /** The name of the code generator, to be included in the agent header. */
    const CODEGEN_NAME = 'gapic';

    /** The default scopes required by the service. */
    public static $serviceScopes = [
        'https://www.googleapis.com/auth/analytics.edit',
        'https://www.googleapis.com/auth/analytics.readonly',
    ];

    private static $accountNameTemplate;

    private static $conversionEventNameTemplate;

    private static $customDimensionNameTemplate;

    private static $customMetricNameTemplate;

    private static $dataRetentionSettingsNameTemplate;

    private static $dataSharingSettingsNameTemplate;

    private static $dataStreamNameTemplate;

    private static $firebaseLinkNameTemplate;

    private static $googleAdsLinkNameTemplate;

    private static $measurementProtocolSecretNameTemplate;

    private static $propertyNameTemplate;

    private static $pathTemplateMap;

    private static function getClientDefaults()
    {
        return [
            'serviceName' => self::SERVICE_NAME,
            'apiEndpoint' => self::SERVICE_ADDRESS . ':' . self::DEFAULT_SERVICE_PORT,
            'clientConfig' => __DIR__ . '/../resources/analytics_admin_service_client_config.json',
            'descriptorsConfigPath' => __DIR__ . '/../resources/analytics_admin_service_descriptor_config.php',
            'gcpApiConfigPath' => __DIR__ . '/../resources/analytics_admin_service_grpc_config.json',
            'credentialsConfig' => [
                'defaultScopes' => self::$serviceScopes,
            ],
            'transportConfig' => [
                'rest' => [
                    'restClientConfigPath' => __DIR__ . '/../resources/analytics_admin_service_rest_client_config.php',
                ],
            ],
        ];
    }

    private static function getAccountNameTemplate()
    {
        if (self::$accountNameTemplate == null) {
            self::$accountNameTemplate = new PathTemplate('accounts/{account}');
        }

        return self::$accountNameTemplate;
    }

    private static function getConversionEventNameTemplate()
    {
        if (self::$conversionEventNameTemplate == null) {
            self::$conversionEventNameTemplate = new PathTemplate('properties/{property}/conversionEvents/{conversion_event}');
        }

        return self::$conversionEventNameTemplate;
    }

    private static function getCustomDimensionNameTemplate()
    {
        if (self::$customDimensionNameTemplate == null) {
            self::$customDimensionNameTemplate = new PathTemplate('properties/{property}/customDimensions/{custom_dimension}');
        }

        return self::$customDimensionNameTemplate;
    }

    private static function getCustomMetricNameTemplate()
    {
        if (self::$customMetricNameTemplate == null) {
            self::$customMetricNameTemplate = new PathTemplate('properties/{property}/customMetrics/{custom_metric}');
        }

        return self::$customMetricNameTemplate;
    }

    private static function getDataRetentionSettingsNameTemplate()
    {
        if (self::$dataRetentionSettingsNameTemplate == null) {
            self::$dataRetentionSettingsNameTemplate = new PathTemplate('properties/{property}/dataRetentionSettings');
        }

        return self::$dataRetentionSettingsNameTemplate;
    }

    private static function getDataSharingSettingsNameTemplate()
    {
        if (self::$dataSharingSettingsNameTemplate == null) {
            self::$dataSharingSettingsNameTemplate = new PathTemplate('accounts/{account}/dataSharingSettings');
        }

        return self::$dataSharingSettingsNameTemplate;
    }

    private static function getDataStreamNameTemplate()
    {
        if (self::$dataStreamNameTemplate == null) {
            self::$dataStreamNameTemplate = new PathTemplate('properties/{property}/dataStreams/{data_stream}');
        }

        return self::$dataStreamNameTemplate;
    }

    private static function getFirebaseLinkNameTemplate()
    {
        if (self::$firebaseLinkNameTemplate == null) {
            self::$firebaseLinkNameTemplate = new PathTemplate('properties/{property}/firebaseLinks/{firebase_link}');
        }

        return self::$firebaseLinkNameTemplate;
    }

    private static function getGoogleAdsLinkNameTemplate()
    {
        if (self::$googleAdsLinkNameTemplate == null) {
            self::$googleAdsLinkNameTemplate = new PathTemplate('properties/{property}/googleAdsLinks/{google_ads_link}');
        }

        return self::$googleAdsLinkNameTemplate;
    }

    private static function getMeasurementProtocolSecretNameTemplate()
    {
        if (self::$measurementProtocolSecretNameTemplate == null) {
            self::$measurementProtocolSecretNameTemplate = new PathTemplate('properties/{property}/dataStreams/{data_stream}/measurementProtocolSecrets/{measurement_protocol_secret}');
        }

        return self::$measurementProtocolSecretNameTemplate;
    }

    private static function getPropertyNameTemplate()
    {
        if (self::$propertyNameTemplate == null) {
            self::$propertyNameTemplate = new PathTemplate('properties/{property}');
        }

        return self::$propertyNameTemplate;
    }

    private static function getPathTemplateMap()
    {
        if (self::$pathTemplateMap == null) {
            self::$pathTemplateMap = [
                'account' => self::getAccountNameTemplate(),
                'conversionEvent' => self::getConversionEventNameTemplate(),
                'customDimension' => self::getCustomDimensionNameTemplate(),
                'customMetric' => self::getCustomMetricNameTemplate(),
                'dataRetentionSettings' => self::getDataRetentionSettingsNameTemplate(),
                'dataSharingSettings' => self::getDataSharingSettingsNameTemplate(),
                'dataStream' => self::getDataStreamNameTemplate(),
                'firebaseLink' => self::getFirebaseLinkNameTemplate(),
                'googleAdsLink' => self::getGoogleAdsLinkNameTemplate(),
                'measurementProtocolSecret' => self::getMeasurementProtocolSecretNameTemplate(),
                'property' => self::getPropertyNameTemplate(),
            ];
        }

        return self::$pathTemplateMap;
    }

    /**
     * Formats a string containing the fully-qualified path to represent a account
     * resource.
     *
     * @param string $account
     *
     * @return string The formatted account resource.
     *
     * @experimental
     */
    public static function accountName($account)
    {
        return self::getAccountNameTemplate()->render([
            'account' => $account,
        ]);
    }

    /**
     * Formats a string containing the fully-qualified path to represent a
     * conversion_event resource.
     *
     * @param string $property
     * @param string $conversionEvent
     *
     * @return string The formatted conversion_event resource.
     *
     * @experimental
     */
    public static function conversionEventName($property, $conversionEvent)
    {
        return self::getConversionEventNameTemplate()->render([
            'property' => $property,
            'conversion_event' => $conversionEvent,
        ]);
    }

    /**
     * Formats a string containing the fully-qualified path to represent a
     * custom_dimension resource.
     *
     * @param string $property
     * @param string $customDimension
     *
     * @return string The formatted custom_dimension resource.
     *
     * @experimental
     */
    public static function customDimensionName($property, $customDimension)
    {
        return self::getCustomDimensionNameTemplate()->render([
            'property' => $property,
            'custom_dimension' => $customDimension,
        ]);
    }

    /**
     * Formats a string containing the fully-qualified path to represent a
     * custom_metric resource.
     *
     * @param string $property
     * @param string $customMetric
     *
     * @return string The formatted custom_metric resource.
     *
     * @experimental
     */
    public static function customMetricName($property, $customMetric)
    {
        return self::getCustomMetricNameTemplate()->render([
            'property' => $property,
            'custom_metric' => $customMetric,
        ]);
    }

    /**
     * Formats a string containing the fully-qualified path to represent a
     * data_retention_settings resource.
     *
     * @param string $property
     *
     * @return string The formatted data_retention_settings resource.
     *
     * @experimental
     */
    public static function dataRetentionSettingsName($property)
    {
        return self::getDataRetentionSettingsNameTemplate()->render([
            'property' => $property,
        ]);
    }

    /**
     * Formats a string containing the fully-qualified path to represent a
     * data_sharing_settings resource.
     *
     * @param string $account
     *
     * @return string The formatted data_sharing_settings resource.
     *
     * @experimental
     */
    public static function dataSharingSettingsName($account)
    {
        return self::getDataSharingSettingsNameTemplate()->render([
            'account' => $account,
        ]);
    }

    /**
     * Formats a string containing the fully-qualified path to represent a data_stream
     * resource.
     *
     * @param string $property
     * @param string $dataStream
     *
     * @return string The formatted data_stream resource.
     *
     * @experimental
     */
    public static function dataStreamName($property, $dataStream)
    {
        return self::getDataStreamNameTemplate()->render([
            'property' => $property,
            'data_stream' => $dataStream,
        ]);
    }

    /**
     * Formats a string containing the fully-qualified path to represent a
     * firebase_link resource.
     *
     * @param string $property
     * @param string $firebaseLink
     *
     * @return string The formatted firebase_link resource.
     *
     * @experimental
     */
    public static function firebaseLinkName($property, $firebaseLink)
    {
        return self::getFirebaseLinkNameTemplate()->render([
            'property' => $property,
            'firebase_link' => $firebaseLink,
        ]);
    }

    /**
     * Formats a string containing the fully-qualified path to represent a
     * google_ads_link resource.
     *
     * @param string $property
     * @param string $googleAdsLink
     *
     * @return string The formatted google_ads_link resource.
     *
     * @experimental
     */
    public static function googleAdsLinkName($property, $googleAdsLink)
    {
        return self::getGoogleAdsLinkNameTemplate()->render([
            'property' => $property,
            'google_ads_link' => $googleAdsLink,
        ]);
    }

    /**
     * Formats a string containing the fully-qualified path to represent a
     * measurement_protocol_secret resource.
     *
     * @param string $property
     * @param string $dataStream
     * @param string $measurementProtocolSecret
     *
     * @return string The formatted measurement_protocol_secret resource.
     *
     * @experimental
     */
    public static function measurementProtocolSecretName($property, $dataStream, $measurementProtocolSecret)
    {
        return self::getMeasurementProtocolSecretNameTemplate()->render([
            'property' => $property,
            'data_stream' => $dataStream,
            'measurement_protocol_secret' => $measurementProtocolSecret,
        ]);
    }

    /**
     * Formats a string containing the fully-qualified path to represent a property
     * resource.
     *
     * @param string $property
     *
     * @return string The formatted property resource.
     *
     * @experimental
     */
    public static function propertyName($property)
    {
        return self::getPropertyNameTemplate()->render([
            'property' => $property,
        ]);
    }

    /**
     * Parses a formatted name string and returns an associative array of the components in the name.
     * The following name formats are supported:
     * Template: Pattern
     * - account: accounts/{account}
     * - conversionEvent: properties/{property}/conversionEvents/{conversion_event}
     * - customDimension: properties/{property}/customDimensions/{custom_dimension}
     * - customMetric: properties/{property}/customMetrics/{custom_metric}
     * - dataRetentionSettings: properties/{property}/dataRetentionSettings
     * - dataSharingSettings: accounts/{account}/dataSharingSettings
     * - dataStream: properties/{property}/dataStreams/{data_stream}
     * - firebaseLink: properties/{property}/firebaseLinks/{firebase_link}
     * - googleAdsLink: properties/{property}/googleAdsLinks/{google_ads_link}
     * - measurementProtocolSecret: properties/{property}/dataStreams/{data_stream}/measurementProtocolSecrets/{measurement_protocol_secret}
     * - property: properties/{property}
     *
     * The optional $template argument can be supplied to specify a particular pattern,
     * and must match one of the templates listed above. If no $template argument is
     * provided, or if the $template argument does not match one of the templates
     * listed, then parseName will check each of the supported templates, and return
     * the first match.
     *
     * @param string $formattedName The formatted name string
     * @param string $template      Optional name of template to match
     *
     * @return array An associative array from name component IDs to component values.
     *
     * @throws ValidationException If $formattedName could not be matched.
     *
     * @experimental
     */
    public static function parseName($formattedName, $template = null)
    {
        $templateMap = self::getPathTemplateMap();
        if ($template) {
            if (!isset($templateMap[$template])) {
                throw new ValidationException("Template name $template does not exist");
            }

            return $templateMap[$template]->match($formattedName);
        }

        foreach ($templateMap as $templateName => $pathTemplate) {
            try {
                return $pathTemplate->match($formattedName);
            } catch (ValidationException $ex) {
                // Swallow the exception to continue trying other path templates
            }
        }

        throw new ValidationException("Input did not match any known format. Input: $formattedName");
    }

    /**
     * Constructor.
     *
     * @param array $options {
     *     Optional. Options for configuring the service API wrapper.
     *
     *     @type string $apiEndpoint
     *           The address of the API remote host. May optionally include the port, formatted
     *           as "<uri>:<port>". Default 'analyticsadmin.googleapis.com:443'.
     *     @type string|array|FetchAuthTokenInterface|CredentialsWrapper $credentials
     *           The credentials to be used by the client to authorize API calls. This option
     *           accepts either a path to a credentials file, or a decoded credentials file as a
     *           PHP array.
     *           *Advanced usage*: In addition, this option can also accept a pre-constructed
     *           {@see \Google\Auth\FetchAuthTokenInterface} object or
     *           {@see \Google\ApiCore\CredentialsWrapper} object. Note that when one of these
     *           objects are provided, any settings in $credentialsConfig will be ignored.
     *     @type array $credentialsConfig
     *           Options used to configure credentials, including auth token caching, for the
     *           client. For a full list of supporting configuration options, see
     *           {@see \Google\ApiCore\CredentialsWrapper::build()} .
     *     @type bool $disableRetries
     *           Determines whether or not retries defined by the client configuration should be
     *           disabled. Defaults to `false`.
     *     @type string|array $clientConfig
     *           Client method configuration, including retry settings. This option can be either
     *           a path to a JSON file, or a PHP array containing the decoded JSON data. By
     *           default this settings points to the default client config file, which is
     *           provided in the resources folder.
     *     @type string|TransportInterface $transport
     *           The transport used for executing network requests. May be either the string
     *           `rest` or `grpc`. Defaults to `grpc` if gRPC support is detected on the system.
     *           *Advanced usage*: Additionally, it is possible to pass in an already
     *           instantiated {@see \Google\ApiCore\Transport\TransportInterface} object. Note
     *           that when this object is provided, any settings in $transportConfig, and any
     *           $apiEndpoint setting, will be ignored.
     *     @type array $transportConfig
     *           Configuration options that will be used to construct the transport. Options for
     *           each supported transport type should be passed in a key for that transport. For
     *           example:
     *           $transportConfig = [
     *               'grpc' => [...],
     *               'rest' => [...],
     *           ];
     *           See the {@see \Google\ApiCore\Transport\GrpcTransport::build()} and
     *           {@see \Google\ApiCore\Transport\RestTransport::build()} methods for the
     *           supported options.
     *     @type callable $clientCertSource
     *           A callable which returns the client cert as a string. This can be used to
     *           provide a certificate and private key to the transport layer for mTLS.
     * }
     *
     * @throws ValidationException
     *
     * @experimental
     */
    public function __construct(array $options = [])
    {
        $clientOptions = $this->buildClientOptions($options);
        $this->setClientOptions($clientOptions);
    }

    /**
     * Acknowledges the terms of user data collection for the specified property.
     *
     * This acknowledgement must be completed (either in the Google Analytics UI
     * or via this API) before MeasurementProtocolSecret resources may be created.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedProperty = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     $acknowledgement = 'acknowledgement';
     *     $response = $analyticsAdminServiceClient->acknowledgeUserDataCollection($formattedProperty, $acknowledgement);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $property        Required. The property for which to acknowledge user data collection.
     * @param string $acknowledgement Required. An acknowledgement that the caller of this method understands the terms
     *                                of user data collection.
     *
     *                                This field must contain the exact value:
     *                                "I acknowledge that I have the necessary privacy disclosures and rights
     *                                from my end users for the collection and processing of their data,
     *                                including the association of such data with the visitation information
     *                                Google Analytics collects from my site and/or app property."
     * @param array  $optionalArgs    {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\AcknowledgeUserDataCollectionResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function acknowledgeUserDataCollection($property, $acknowledgement, array $optionalArgs = [])
    {
        $request = new AcknowledgeUserDataCollectionRequest();
        $requestParamHeaders = [];
        $request->setProperty($property);
        $request->setAcknowledgement($acknowledgement);
        $requestParamHeaders['property'] = $property;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('AcknowledgeUserDataCollection', AcknowledgeUserDataCollectionResponse::class, $optionalArgs, $request)->wait();
    }

    /**
     * Archives a CustomDimension on a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->customDimensionName('[PROPERTY]', '[CUSTOM_DIMENSION]');
     *     $analyticsAdminServiceClient->archiveCustomDimension($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the CustomDimension to archive.
     *                             Example format: properties/1234/customDimensions/5678
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function archiveCustomDimension($name, array $optionalArgs = [])
    {
        $request = new ArchiveCustomDimensionRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('ArchiveCustomDimension', GPBEmpty::class, $optionalArgs, $request)->wait();
    }

    /**
     * Archives a CustomMetric on a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->customMetricName('[PROPERTY]', '[CUSTOM_METRIC]');
     *     $analyticsAdminServiceClient->archiveCustomMetric($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the CustomMetric to archive.
     *                             Example format: properties/1234/customMetrics/5678
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function archiveCustomMetric($name, array $optionalArgs = [])
    {
        $request = new ArchiveCustomMetricRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('ArchiveCustomMetric', GPBEmpty::class, $optionalArgs, $request)->wait();
    }

    /**
     * Creates a conversion event with the specified attributes.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $conversionEvent = new ConversionEvent();
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     $response = $analyticsAdminServiceClient->createConversionEvent($conversionEvent, $formattedParent);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param ConversionEvent $conversionEvent Required. The conversion event to create.
     * @param string          $parent          Required. The resource name of the parent property where this conversion event will
     *                                         be created. Format: properties/123
     * @param array           $optionalArgs    {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\ConversionEvent
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function createConversionEvent($conversionEvent, $parent, array $optionalArgs = [])
    {
        $request = new CreateConversionEventRequest();
        $requestParamHeaders = [];
        $request->setConversionEvent($conversionEvent);
        $request->setParent($parent);
        $requestParamHeaders['parent'] = $parent;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('CreateConversionEvent', ConversionEvent::class, $optionalArgs, $request)->wait();
    }

    /**
     * Creates a CustomDimension.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     $customDimension = new CustomDimension();
     *     $response = $analyticsAdminServiceClient->createCustomDimension($formattedParent, $customDimension);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string          $parent          Required. Example format: properties/1234
     * @param CustomDimension $customDimension Required. The CustomDimension to create.
     * @param array           $optionalArgs    {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\CustomDimension
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function createCustomDimension($parent, $customDimension, array $optionalArgs = [])
    {
        $request = new CreateCustomDimensionRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $request->setCustomDimension($customDimension);
        $requestParamHeaders['parent'] = $parent;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('CreateCustomDimension', CustomDimension::class, $optionalArgs, $request)->wait();
    }

    /**
     * Creates a CustomMetric.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     $customMetric = new CustomMetric();
     *     $response = $analyticsAdminServiceClient->createCustomMetric($formattedParent, $customMetric);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string       $parent       Required. Example format: properties/1234
     * @param CustomMetric $customMetric Required. The CustomMetric to create.
     * @param array        $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\CustomMetric
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function createCustomMetric($parent, $customMetric, array $optionalArgs = [])
    {
        $request = new CreateCustomMetricRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $request->setCustomMetric($customMetric);
        $requestParamHeaders['parent'] = $parent;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('CreateCustomMetric', CustomMetric::class, $optionalArgs, $request)->wait();
    }

    /**
     * Creates a DataStream.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     $dataStream = new DataStream();
     *     $response = $analyticsAdminServiceClient->createDataStream($formattedParent, $dataStream);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string     $parent       Required. Example format: properties/1234
     * @param DataStream $dataStream   Required. The DataStream to create.
     * @param array      $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\DataStream
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function createDataStream($parent, $dataStream, array $optionalArgs = [])
    {
        $request = new CreateDataStreamRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $request->setDataStream($dataStream);
        $requestParamHeaders['parent'] = $parent;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('CreateDataStream', DataStream::class, $optionalArgs, $request)->wait();
    }

    /**
     * Creates a FirebaseLink.
     *
     * Properties can have at most one FirebaseLink.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     $firebaseLink = new FirebaseLink();
     *     $response = $analyticsAdminServiceClient->createFirebaseLink($formattedParent, $firebaseLink);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string       $parent       Required. Format: properties/{property_id}
     *                                   Example: properties/1234
     * @param FirebaseLink $firebaseLink Required. The Firebase link to create.
     * @param array        $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\FirebaseLink
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function createFirebaseLink($parent, $firebaseLink, array $optionalArgs = [])
    {
        $request = new CreateFirebaseLinkRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $request->setFirebaseLink($firebaseLink);
        $requestParamHeaders['parent'] = $parent;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('CreateFirebaseLink', FirebaseLink::class, $optionalArgs, $request)->wait();
    }

    /**
     * Creates a GoogleAdsLink.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     $googleAdsLink = new GoogleAdsLink();
     *     $response = $analyticsAdminServiceClient->createGoogleAdsLink($formattedParent, $googleAdsLink);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string        $parent        Required. Example format: properties/1234
     * @param GoogleAdsLink $googleAdsLink Required. The GoogleAdsLink to create.
     * @param array         $optionalArgs  {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\GoogleAdsLink
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function createGoogleAdsLink($parent, $googleAdsLink, array $optionalArgs = [])
    {
        $request = new CreateGoogleAdsLinkRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $request->setGoogleAdsLink($googleAdsLink);
        $requestParamHeaders['parent'] = $parent;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('CreateGoogleAdsLink', GoogleAdsLink::class, $optionalArgs, $request)->wait();
    }

    /**
     * Creates a measurement protocol secret.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->dataStreamName('[PROPERTY]', '[DATA_STREAM]');
     *     $measurementProtocolSecret = new MeasurementProtocolSecret();
     *     $response = $analyticsAdminServiceClient->createMeasurementProtocolSecret($formattedParent, $measurementProtocolSecret);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string                    $parent                    Required. The parent resource where this secret will be created.
     *                                                             Format: properties/{property}/dataStreams/{dataStream}
     * @param MeasurementProtocolSecret $measurementProtocolSecret Required. The measurement protocol secret to create.
     * @param array                     $optionalArgs              {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\MeasurementProtocolSecret
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function createMeasurementProtocolSecret($parent, $measurementProtocolSecret, array $optionalArgs = [])
    {
        $request = new CreateMeasurementProtocolSecretRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $request->setMeasurementProtocolSecret($measurementProtocolSecret);
        $requestParamHeaders['parent'] = $parent;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('CreateMeasurementProtocolSecret', MeasurementProtocolSecret::class, $optionalArgs, $request)->wait();
    }

    /**
     * Creates an "GA4" property with the specified location and attributes.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $property = new Property();
     *     $response = $analyticsAdminServiceClient->createProperty($property);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param Property $property     Required. The property to create.
     *                               Note: the supplied property must specify its parent.
     * @param array    $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\Property
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function createProperty($property, array $optionalArgs = [])
    {
        $request = new CreatePropertyRequest();
        $request->setProperty($property);
        return $this->startCall('CreateProperty', Property::class, $optionalArgs, $request)->wait();
    }

    /**
     * Marks target Account as soft-deleted (ie: "trashed") and returns it.
     *
     * This API does not have a method to restore soft-deleted accounts.
     * However, they can be restored using the Trash Can UI.
     *
     * If the accounts are not restored before the expiration time, the account
     * and all child resources (eg: Properties, GoogleAdsLinks, Streams,
     * UserLinks) will be permanently purged.
     * https://support.google.com/analytics/answer/6154772
     *
     * Returns an error if the target is not found.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->accountName('[ACCOUNT]');
     *     $analyticsAdminServiceClient->deleteAccount($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the Account to soft-delete.
     *                             Format: accounts/{account}
     *                             Example: "accounts/100"
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function deleteAccount($name, array $optionalArgs = [])
    {
        $request = new DeleteAccountRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('DeleteAccount', GPBEmpty::class, $optionalArgs, $request)->wait();
    }

    /**
     * Deletes a conversion event in a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->conversionEventName('[PROPERTY]', '[CONVERSION_EVENT]');
     *     $analyticsAdminServiceClient->deleteConversionEvent($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The resource name of the conversion event to delete.
     *                             Format: properties/{property}/conversionEvents/{conversion_event}
     *                             Example: "properties/123/conversionEvents/456"
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function deleteConversionEvent($name, array $optionalArgs = [])
    {
        $request = new DeleteConversionEventRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('DeleteConversionEvent', GPBEmpty::class, $optionalArgs, $request)->wait();
    }

    /**
     * Deletes a DataStream on a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->dataStreamName('[PROPERTY]', '[DATA_STREAM]');
     *     $analyticsAdminServiceClient->deleteDataStream($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the DataStream to delete.
     *                             Example format: properties/1234/dataStreams/5678
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function deleteDataStream($name, array $optionalArgs = [])
    {
        $request = new DeleteDataStreamRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('DeleteDataStream', GPBEmpty::class, $optionalArgs, $request)->wait();
    }

    /**
     * Deletes a FirebaseLink on a property
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->firebaseLinkName('[PROPERTY]', '[FIREBASE_LINK]');
     *     $analyticsAdminServiceClient->deleteFirebaseLink($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. Format: properties/{property_id}/firebaseLinks/{firebase_link_id}
     *                             Example: properties/1234/firebaseLinks/5678
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function deleteFirebaseLink($name, array $optionalArgs = [])
    {
        $request = new DeleteFirebaseLinkRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('DeleteFirebaseLink', GPBEmpty::class, $optionalArgs, $request)->wait();
    }

    /**
     * Deletes a GoogleAdsLink on a property
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->googleAdsLinkName('[PROPERTY]', '[GOOGLE_ADS_LINK]');
     *     $analyticsAdminServiceClient->deleteGoogleAdsLink($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. Example format: properties/1234/googleAdsLinks/5678
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function deleteGoogleAdsLink($name, array $optionalArgs = [])
    {
        $request = new DeleteGoogleAdsLinkRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('DeleteGoogleAdsLink', GPBEmpty::class, $optionalArgs, $request)->wait();
    }

    /**
     * Deletes target MeasurementProtocolSecret.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->measurementProtocolSecretName('[PROPERTY]', '[DATA_STREAM]', '[MEASUREMENT_PROTOCOL_SECRET]');
     *     $analyticsAdminServiceClient->deleteMeasurementProtocolSecret($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the MeasurementProtocolSecret to delete.
     *                             Format:
     *                             properties/{property}/dataStreams/{dataStream}/measurementProtocolSecrets/{measurementProtocolSecret}
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function deleteMeasurementProtocolSecret($name, array $optionalArgs = [])
    {
        $request = new DeleteMeasurementProtocolSecretRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('DeleteMeasurementProtocolSecret', GPBEmpty::class, $optionalArgs, $request)->wait();
    }

    /**
     * Marks target Property as soft-deleted (ie: "trashed") and returns it.
     *
     * This API does not have a method to restore soft-deleted properties.
     * However, they can be restored using the Trash Can UI.
     *
     * If the properties are not restored before the expiration time, the Property
     * and all child resources (eg: GoogleAdsLinks, Streams, UserLinks)
     * will be permanently purged.
     * https://support.google.com/analytics/answer/6154772
     *
     * Returns an error if the target is not found, or is not an GA4 Property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     $response = $analyticsAdminServiceClient->deleteProperty($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the Property to soft-delete.
     *                             Format: properties/{property_id}
     *                             Example: "properties/1000"
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\Property
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function deleteProperty($name, array $optionalArgs = [])
    {
        $request = new DeletePropertyRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('DeleteProperty', Property::class, $optionalArgs, $request)->wait();
    }

    /**
     * Lookup for a single Account.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->accountName('[ACCOUNT]');
     *     $response = $analyticsAdminServiceClient->getAccount($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the account to lookup.
     *                             Format: accounts/{account}
     *                             Example: "accounts/100"
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\Account
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function getAccount($name, array $optionalArgs = [])
    {
        $request = new GetAccountRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('GetAccount', Account::class, $optionalArgs, $request)->wait();
    }

    /**
     * Retrieve a single conversion event.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->conversionEventName('[PROPERTY]', '[CONVERSION_EVENT]');
     *     $response = $analyticsAdminServiceClient->getConversionEvent($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The resource name of the conversion event to retrieve.
     *                             Format: properties/{property}/conversionEvents/{conversion_event}
     *                             Example: "properties/123/conversionEvents/456"
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\ConversionEvent
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function getConversionEvent($name, array $optionalArgs = [])
    {
        $request = new GetConversionEventRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('GetConversionEvent', ConversionEvent::class, $optionalArgs, $request)->wait();
    }

    /**
     * Lookup for a single CustomDimension.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->customDimensionName('[PROPERTY]', '[CUSTOM_DIMENSION]');
     *     $response = $analyticsAdminServiceClient->getCustomDimension($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the CustomDimension to get.
     *                             Example format: properties/1234/customDimensions/5678
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\CustomDimension
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function getCustomDimension($name, array $optionalArgs = [])
    {
        $request = new GetCustomDimensionRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('GetCustomDimension', CustomDimension::class, $optionalArgs, $request)->wait();
    }

    /**
     * Lookup for a single CustomMetric.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->customMetricName('[PROPERTY]', '[CUSTOM_METRIC]');
     *     $response = $analyticsAdminServiceClient->getCustomMetric($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the CustomMetric to get.
     *                             Example format: properties/1234/customMetrics/5678
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\CustomMetric
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function getCustomMetric($name, array $optionalArgs = [])
    {
        $request = new GetCustomMetricRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('GetCustomMetric', CustomMetric::class, $optionalArgs, $request)->wait();
    }

    /**
     * Returns the singleton data retention settings for this property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->dataRetentionSettingsName('[PROPERTY]');
     *     $response = $analyticsAdminServiceClient->getDataRetentionSettings($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the settings to lookup.
     *                             Format:
     *                             properties/{property}/dataRetentionSettings
     *                             Example: "properties/1000/dataRetentionSettings"
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\DataRetentionSettings
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function getDataRetentionSettings($name, array $optionalArgs = [])
    {
        $request = new GetDataRetentionSettingsRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('GetDataRetentionSettings', DataRetentionSettings::class, $optionalArgs, $request)->wait();
    }

    /**
     * Get data sharing settings on an account.
     * Data sharing settings are singletons.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->dataSharingSettingsName('[ACCOUNT]');
     *     $response = $analyticsAdminServiceClient->getDataSharingSettings($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the settings to lookup.
     *                             Format: accounts/{account}/dataSharingSettings
     *                             Example: "accounts/1000/dataSharingSettings"
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\DataSharingSettings
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function getDataSharingSettings($name, array $optionalArgs = [])
    {
        $request = new GetDataSharingSettingsRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('GetDataSharingSettings', DataSharingSettings::class, $optionalArgs, $request)->wait();
    }

    /**
     * Lookup for a single DataStream.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->dataStreamName('[PROPERTY]', '[DATA_STREAM]');
     *     $response = $analyticsAdminServiceClient->getDataStream($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the DataStream to get.
     *                             Example format: properties/1234/dataStreams/5678
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\DataStream
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function getDataStream($name, array $optionalArgs = [])
    {
        $request = new GetDataStreamRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('GetDataStream', DataStream::class, $optionalArgs, $request)->wait();
    }

    /**
     * Lookup for a single "GA4" MeasurementProtocolSecret.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->measurementProtocolSecretName('[PROPERTY]', '[DATA_STREAM]', '[MEASUREMENT_PROTOCOL_SECRET]');
     *     $response = $analyticsAdminServiceClient->getMeasurementProtocolSecret($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the measurement protocol secret to lookup.
     *                             Format:
     *                             properties/{property}/dataStreams/{dataStream}/measurementProtocolSecrets/{measurementProtocolSecret}
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\MeasurementProtocolSecret
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function getMeasurementProtocolSecret($name, array $optionalArgs = [])
    {
        $request = new GetMeasurementProtocolSecretRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('GetMeasurementProtocolSecret', MeasurementProtocolSecret::class, $optionalArgs, $request)->wait();
    }

    /**
     * Lookup for a single "GA4" Property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedName = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     $response = $analyticsAdminServiceClient->getProperty($formattedName);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $name         Required. The name of the property to lookup.
     *                             Format: properties/{property_id}
     *                             Example: "properties/1000"
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\Property
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function getProperty($name, array $optionalArgs = [])
    {
        $request = new GetPropertyRequest();
        $requestParamHeaders = [];
        $request->setName($name);
        $requestParamHeaders['name'] = $name;
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('GetProperty', Property::class, $optionalArgs, $request)->wait();
    }

    /**
     * Returns summaries of all accounts accessible by the caller.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->listAccountSummaries();
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->listAccountSummaries();
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listAccountSummaries(array $optionalArgs = [])
    {
        $request = new ListAccountSummariesRequest();
        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        return $this->getPagedListResponse('ListAccountSummaries', $optionalArgs, ListAccountSummariesResponse::class, $request);
    }

    /**
     * Returns all accounts accessible by the caller.
     *
     * Note that these accounts might not currently have GA4 properties.
     * Soft-deleted (ie: "trashed") accounts are excluded by default.
     * Returns an empty list if no relevant accounts are found.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->listAccounts();
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->listAccounts();
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type bool $showDeleted
     *           Whether to include soft-deleted (ie: "trashed") Accounts in the
     *           results. Accounts can be inspected to determine whether they are deleted or
     *           not.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listAccounts(array $optionalArgs = [])
    {
        $request = new ListAccountsRequest();
        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        if (isset($optionalArgs['showDeleted'])) {
            $request->setShowDeleted($optionalArgs['showDeleted']);
        }

        return $this->getPagedListResponse('ListAccounts', $optionalArgs, ListAccountsResponse::class, $request);
    }

    /**
     * Returns a list of conversion events in the specified parent property.
     *
     * Returns an empty list if no conversion events are found.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->listConversionEvents($formattedParent);
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->listConversionEvents($formattedParent);
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $parent       Required. The resource name of the parent property.
     *                             Example: 'properties/123'
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listConversionEvents($parent, array $optionalArgs = [])
    {
        $request = new ListConversionEventsRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $requestParamHeaders['parent'] = $parent;
        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->getPagedListResponse('ListConversionEvents', $optionalArgs, ListConversionEventsResponse::class, $request);
    }

    /**
     * Lists CustomDimensions on a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->listCustomDimensions($formattedParent);
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->listCustomDimensions($formattedParent);
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $parent       Required. Example format: properties/1234
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listCustomDimensions($parent, array $optionalArgs = [])
    {
        $request = new ListCustomDimensionsRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $requestParamHeaders['parent'] = $parent;
        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->getPagedListResponse('ListCustomDimensions', $optionalArgs, ListCustomDimensionsResponse::class, $request);
    }

    /**
     * Lists CustomMetrics on a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->listCustomMetrics($formattedParent);
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->listCustomMetrics($formattedParent);
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $parent       Required. Example format: properties/1234
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listCustomMetrics($parent, array $optionalArgs = [])
    {
        $request = new ListCustomMetricsRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $requestParamHeaders['parent'] = $parent;
        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->getPagedListResponse('ListCustomMetrics', $optionalArgs, ListCustomMetricsResponse::class, $request);
    }

    /**
     * Lists DataStreams on a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->listDataStreams($formattedParent);
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->listDataStreams($formattedParent);
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $parent       Required. Example format: properties/1234
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listDataStreams($parent, array $optionalArgs = [])
    {
        $request = new ListDataStreamsRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $requestParamHeaders['parent'] = $parent;
        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->getPagedListResponse('ListDataStreams', $optionalArgs, ListDataStreamsResponse::class, $request);
    }

    /**
     * Lists FirebaseLinks on a property.
     * Properties can have at most one FirebaseLink.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->listFirebaseLinks($formattedParent);
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->listFirebaseLinks($formattedParent);
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $parent       Required. Format: properties/{property_id}
     *                             Example: properties/1234
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listFirebaseLinks($parent, array $optionalArgs = [])
    {
        $request = new ListFirebaseLinksRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $requestParamHeaders['parent'] = $parent;
        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->getPagedListResponse('ListFirebaseLinks', $optionalArgs, ListFirebaseLinksResponse::class, $request);
    }

    /**
     * Lists GoogleAdsLinks on a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->propertyName('[PROPERTY]');
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->listGoogleAdsLinks($formattedParent);
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->listGoogleAdsLinks($formattedParent);
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $parent       Required. Example format: properties/1234
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listGoogleAdsLinks($parent, array $optionalArgs = [])
    {
        $request = new ListGoogleAdsLinksRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $requestParamHeaders['parent'] = $parent;
        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->getPagedListResponse('ListGoogleAdsLinks', $optionalArgs, ListGoogleAdsLinksResponse::class, $request);
    }

    /**
     * Returns child MeasurementProtocolSecrets under the specified parent
     * Property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedParent = $analyticsAdminServiceClient->dataStreamName('[PROPERTY]', '[DATA_STREAM]');
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->listMeasurementProtocolSecrets($formattedParent);
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->listMeasurementProtocolSecrets($formattedParent);
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $parent       Required. The resource name of the parent stream.
     *                             Format:
     *                             properties/{property}/dataStreams/{dataStream}/measurementProtocolSecrets
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listMeasurementProtocolSecrets($parent, array $optionalArgs = [])
    {
        $request = new ListMeasurementProtocolSecretsRequest();
        $requestParamHeaders = [];
        $request->setParent($parent);
        $requestParamHeaders['parent'] = $parent;
        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->getPagedListResponse('ListMeasurementProtocolSecrets', $optionalArgs, ListMeasurementProtocolSecretsResponse::class, $request);
    }

    /**
     * Returns child Properties under the specified parent Account.
     *
     * Only "GA4" properties will be returned.
     * Properties will be excluded if the caller does not have access.
     * Soft-deleted (ie: "trashed") properties are excluded by default.
     * Returns an empty list if no relevant properties are found.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $filter = 'filter';
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->listProperties($filter);
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->listProperties($filter);
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $filter       Required. An expression for filtering the results of the request.
     *                             Fields eligible for filtering are:
     *                             `parent:`(The resource name of the parent account/property) or
     *                             `ancestor:`(The resource name of the parent account) or
     *                             `firebase_project:`(The id or number of the linked firebase project).
     *                             Some examples of filters:
     *
     *                             ```
     *                             | Filter                      | Description                               |
     *                             |-----------------------------|-------------------------------------------|
     *                             | parent:accounts/123         | The account with account id: 123.       |
     *                             | parent:properties/123       | The property with property id: 123.       |
     *                             | ancestor:accounts/123       | The account with account id: 123.         |
     *                             | firebase_project:project-id | The firebase project with id: project-id. |
     *                             | firebase_project:123        | The firebase project with number: 123.    |
     *                             ```
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type bool $showDeleted
     *           Whether to include soft-deleted (ie: "trashed") Properties in the
     *           results. Properties can be inspected to determine whether they are deleted
     *           or not.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listProperties($filter, array $optionalArgs = [])
    {
        $request = new ListPropertiesRequest();
        $request->setFilter($filter);
        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        if (isset($optionalArgs['showDeleted'])) {
            $request->setShowDeleted($optionalArgs['showDeleted']);
        }

        return $this->getPagedListResponse('ListProperties', $optionalArgs, ListPropertiesResponse::class, $request);
    }

    /**
     * Requests a ticket for creating an account.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $response = $analyticsAdminServiceClient->provisionAccountTicket();
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type Account $account
     *           The account to create.
     *     @type string $redirectUri
     *           Redirect URI where the user will be sent after accepting Terms of Service.
     *           Must be configured in Developers Console as a Redirect URI
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\ProvisionAccountTicketResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function provisionAccountTicket(array $optionalArgs = [])
    {
        $request = new ProvisionAccountTicketRequest();
        if (isset($optionalArgs['account'])) {
            $request->setAccount($optionalArgs['account']);
        }

        if (isset($optionalArgs['redirectUri'])) {
            $request->setRedirectUri($optionalArgs['redirectUri']);
        }

        return $this->startCall('ProvisionAccountTicket', ProvisionAccountTicketResponse::class, $optionalArgs, $request)->wait();
    }

    /**
     * Searches through all changes to an account or its children given the
     * specified set of filters.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $formattedAccount = $analyticsAdminServiceClient->accountName('[ACCOUNT]');
     *     // Iterate over pages of elements
     *     $pagedResponse = $analyticsAdminServiceClient->searchChangeHistoryEvents($formattedAccount);
     *     foreach ($pagedResponse->iteratePages() as $page) {
     *         foreach ($page as $element) {
     *             // doSomethingWith($element);
     *         }
     *     }
     *     // Alternatively:
     *     // Iterate through all elements
     *     $pagedResponse = $analyticsAdminServiceClient->searchChangeHistoryEvents($formattedAccount);
     *     foreach ($pagedResponse->iterateAllElements() as $element) {
     *         // doSomethingWith($element);
     *     }
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param string $account      Required. The account resource for which to return change history resources.
     * @param array  $optionalArgs {
     *     Optional.
     *
     *     @type string $property
     *           Optional. Resource name for a child property. If set, only return changes
     *           made to this property or its child resources.
     *     @type int[] $resourceType
     *           Optional. If set, only return changes if they are for a resource that matches at
     *           least one of these types.
     *           For allowed values, use constants defined on {@see \Google\Analytics\Admin\V1beta\ChangeHistoryResourceType}
     *     @type int[] $action
     *           Optional. If set, only return changes that match one or more of these types of
     *           actions.
     *           For allowed values, use constants defined on {@see \Google\Analytics\Admin\V1beta\ActionType}
     *     @type string[] $actorEmail
     *           Optional. If set, only return changes if they are made by a user in this list.
     *     @type Timestamp $earliestChangeTime
     *           Optional. If set, only return changes made after this time (inclusive).
     *     @type Timestamp $latestChangeTime
     *           Optional. If set, only return changes made before this time (inclusive).
     *     @type int $pageSize
     *           The maximum number of resources contained in the underlying API
     *           response. The API may return fewer values in a page, even if
     *           there are additional values to be retrieved.
     *     @type string $pageToken
     *           A page token is used to specify a page of values to be returned.
     *           If no page token is specified (the default), the first page
     *           of values will be returned. Any page token used here must have
     *           been generated by a previous call to the API.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\ApiCore\PagedListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function searchChangeHistoryEvents($account, array $optionalArgs = [])
    {
        $request = new SearchChangeHistoryEventsRequest();
        $requestParamHeaders = [];
        $request->setAccount($account);
        $requestParamHeaders['account'] = $account;
        if (isset($optionalArgs['property'])) {
            $request->setProperty($optionalArgs['property']);
        }

        if (isset($optionalArgs['resourceType'])) {
            $request->setResourceType($optionalArgs['resourceType']);
        }

        if (isset($optionalArgs['action'])) {
            $request->setAction($optionalArgs['action']);
        }

        if (isset($optionalArgs['actorEmail'])) {
            $request->setActorEmail($optionalArgs['actorEmail']);
        }

        if (isset($optionalArgs['earliestChangeTime'])) {
            $request->setEarliestChangeTime($optionalArgs['earliestChangeTime']);
        }

        if (isset($optionalArgs['latestChangeTime'])) {
            $request->setLatestChangeTime($optionalArgs['latestChangeTime']);
        }

        if (isset($optionalArgs['pageSize'])) {
            $request->setPageSize($optionalArgs['pageSize']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->getPagedListResponse('SearchChangeHistoryEvents', $optionalArgs, SearchChangeHistoryEventsResponse::class, $request);
    }

    /**
     * Updates an account.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $account = new Account();
     *     $updateMask = new FieldMask();
     *     $response = $analyticsAdminServiceClient->updateAccount($account, $updateMask);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param Account   $account      Required. The account to update.
     *                                The account's `name` field is used to identify the account.
     * @param FieldMask $updateMask   Required. The list of fields to be updated. Field names must be in snake case
     *                                (e.g., "field_to_update"). Omitted fields will not be updated. To replace
     *                                the entire entity, use one path with the string "*" to match all fields.
     * @param array     $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\Account
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function updateAccount($account, $updateMask, array $optionalArgs = [])
    {
        $request = new UpdateAccountRequest();
        $requestParamHeaders = [];
        $request->setAccount($account);
        $request->setUpdateMask($updateMask);
        $requestParamHeaders['account.name'] = $account->getName();
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('UpdateAccount', Account::class, $optionalArgs, $request)->wait();
    }

    /**
     * Updates a CustomDimension on a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $updateMask = new FieldMask();
     *     $response = $analyticsAdminServiceClient->updateCustomDimension($updateMask);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param FieldMask $updateMask   Required. The list of fields to be updated. Omitted fields will not be updated.
     *                                To replace the entire entity, use one path with the string "*" to match
     *                                all fields.
     * @param array     $optionalArgs {
     *     Optional.
     *
     *     @type CustomDimension $customDimension
     *           The CustomDimension to update
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\CustomDimension
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function updateCustomDimension($updateMask, array $optionalArgs = [])
    {
        $request = new UpdateCustomDimensionRequest();
        $requestParamHeaders = [];
        $request->setUpdateMask($updateMask);
        if (isset($optionalArgs['customDimension'])) {
            $request->setCustomDimension($optionalArgs['customDimension']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('UpdateCustomDimension', CustomDimension::class, $optionalArgs, $request)->wait();
    }

    /**
     * Updates a CustomMetric on a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $updateMask = new FieldMask();
     *     $response = $analyticsAdminServiceClient->updateCustomMetric($updateMask);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param FieldMask $updateMask   Required. The list of fields to be updated. Omitted fields will not be updated.
     *                                To replace the entire entity, use one path with the string "*" to match
     *                                all fields.
     * @param array     $optionalArgs {
     *     Optional.
     *
     *     @type CustomMetric $customMetric
     *           The CustomMetric to update
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\CustomMetric
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function updateCustomMetric($updateMask, array $optionalArgs = [])
    {
        $request = new UpdateCustomMetricRequest();
        $requestParamHeaders = [];
        $request->setUpdateMask($updateMask);
        if (isset($optionalArgs['customMetric'])) {
            $request->setCustomMetric($optionalArgs['customMetric']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('UpdateCustomMetric', CustomMetric::class, $optionalArgs, $request)->wait();
    }

    /**
     * Updates the singleton data retention settings for this property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $dataRetentionSettings = new DataRetentionSettings();
     *     $updateMask = new FieldMask();
     *     $response = $analyticsAdminServiceClient->updateDataRetentionSettings($dataRetentionSettings, $updateMask);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param DataRetentionSettings $dataRetentionSettings Required. The settings to update.
     *                                                     The `name` field is used to identify the settings to be updated.
     * @param FieldMask             $updateMask            Required. The list of fields to be updated. Field names must be in snake case
     *                                                     (e.g., "field_to_update"). Omitted fields will not be updated. To replace
     *                                                     the entire entity, use one path with the string "*" to match all fields.
     * @param array                 $optionalArgs          {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\DataRetentionSettings
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function updateDataRetentionSettings($dataRetentionSettings, $updateMask, array $optionalArgs = [])
    {
        $request = new UpdateDataRetentionSettingsRequest();
        $requestParamHeaders = [];
        $request->setDataRetentionSettings($dataRetentionSettings);
        $request->setUpdateMask($updateMask);
        $requestParamHeaders['data_retention_settings.name'] = $dataRetentionSettings->getName();
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('UpdateDataRetentionSettings', DataRetentionSettings::class, $optionalArgs, $request)->wait();
    }

    /**
     * Updates a DataStream on a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $updateMask = new FieldMask();
     *     $response = $analyticsAdminServiceClient->updateDataStream($updateMask);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param FieldMask $updateMask   Required. The list of fields to be updated. Omitted fields will not be updated.
     *                                To replace the entire entity, use one path with the string "*" to match
     *                                all fields.
     * @param array     $optionalArgs {
     *     Optional.
     *
     *     @type DataStream $dataStream
     *           The DataStream to update
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\DataStream
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function updateDataStream($updateMask, array $optionalArgs = [])
    {
        $request = new UpdateDataStreamRequest();
        $requestParamHeaders = [];
        $request->setUpdateMask($updateMask);
        if (isset($optionalArgs['dataStream'])) {
            $request->setDataStream($optionalArgs['dataStream']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('UpdateDataStream', DataStream::class, $optionalArgs, $request)->wait();
    }

    /**
     * Updates a GoogleAdsLink on a property
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $updateMask = new FieldMask();
     *     $response = $analyticsAdminServiceClient->updateGoogleAdsLink($updateMask);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param FieldMask $updateMask   Required. The list of fields to be updated. Field names must be in snake case
     *                                (e.g., "field_to_update"). Omitted fields will not be updated. To replace
     *                                the entire entity, use one path with the string "*" to match all fields.
     * @param array     $optionalArgs {
     *     Optional.
     *
     *     @type GoogleAdsLink $googleAdsLink
     *           The GoogleAdsLink to update
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\GoogleAdsLink
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function updateGoogleAdsLink($updateMask, array $optionalArgs = [])
    {
        $request = new UpdateGoogleAdsLinkRequest();
        $requestParamHeaders = [];
        $request->setUpdateMask($updateMask);
        if (isset($optionalArgs['googleAdsLink'])) {
            $request->setGoogleAdsLink($optionalArgs['googleAdsLink']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('UpdateGoogleAdsLink', GoogleAdsLink::class, $optionalArgs, $request)->wait();
    }

    /**
     * Updates a measurement protocol secret.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $measurementProtocolSecret = new MeasurementProtocolSecret();
     *     $response = $analyticsAdminServiceClient->updateMeasurementProtocolSecret($measurementProtocolSecret);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param MeasurementProtocolSecret $measurementProtocolSecret Required. The measurement protocol secret to update.
     * @param array                     $optionalArgs              {
     *     Optional.
     *
     *     @type FieldMask $updateMask
     *           The list of fields to be updated. Omitted fields will not be updated.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\MeasurementProtocolSecret
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function updateMeasurementProtocolSecret($measurementProtocolSecret, array $optionalArgs = [])
    {
        $request = new UpdateMeasurementProtocolSecretRequest();
        $requestParamHeaders = [];
        $request->setMeasurementProtocolSecret($measurementProtocolSecret);
        $requestParamHeaders['measurement_protocol_secret.name'] = $measurementProtocolSecret->getName();
        if (isset($optionalArgs['updateMask'])) {
            $request->setUpdateMask($optionalArgs['updateMask']);
        }

        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('UpdateMeasurementProtocolSecret', MeasurementProtocolSecret::class, $optionalArgs, $request)->wait();
    }

    /**
     * Updates a property.
     *
     * Sample code:
     * ```
     * $analyticsAdminServiceClient = new AnalyticsAdminServiceClient();
     * try {
     *     $property = new Property();
     *     $updateMask = new FieldMask();
     *     $response = $analyticsAdminServiceClient->updateProperty($property, $updateMask);
     * } finally {
     *     $analyticsAdminServiceClient->close();
     * }
     * ```
     *
     * @param Property  $property     Required. The property to update.
     *                                The property's `name` field is used to identify the property to be
     *                                updated.
     * @param FieldMask $updateMask   Required. The list of fields to be updated. Field names must be in snake case
     *                                (e.g., "field_to_update"). Omitted fields will not be updated. To replace
     *                                the entire entity, use one path with the string "*" to match all fields.
     * @param array     $optionalArgs {
     *     Optional.
     *
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Analytics\Admin\V1beta\Property
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function updateProperty($property, $updateMask, array $optionalArgs = [])
    {
        $request = new UpdatePropertyRequest();
        $requestParamHeaders = [];
        $request->setProperty($property);
        $request->setUpdateMask($updateMask);
        $requestParamHeaders['property.name'] = $property->getName();
        $requestParams = new RequestParamsHeaderDescriptor($requestParamHeaders);
        $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader();
        return $this->startCall('UpdateProperty', Property::class, $optionalArgs, $request)->wait();
    }
}
