// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.
package com.azure.developer.loadtesting;

import com.azure.core.annotation.Generated;
import com.azure.core.annotation.ReturnType;
import com.azure.core.annotation.ServiceClient;
import com.azure.core.annotation.ServiceMethod;
import com.azure.core.exception.ClientAuthenticationException;
import com.azure.core.exception.HttpResponseException;
import com.azure.core.exception.ResourceModifiedException;
import com.azure.core.exception.ResourceNotFoundException;
import com.azure.core.http.rest.PagedFlux;
import com.azure.core.http.rest.RequestOptions;
import com.azure.core.http.rest.Response;
import com.azure.core.util.BinaryData;
import com.azure.core.util.FluxUtil;
import com.azure.core.util.polling.LongRunningOperationStatus;
import com.azure.core.util.polling.PollResponse;
import com.azure.core.util.polling.PollerFlux;
import com.azure.developer.loadtesting.implementation.LoadTestAdministrationsImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Duration;
import reactor.core.publisher.Mono;

/** Initializes a new instance of the asynchronous LoadTestingClient type. */
@ServiceClient(builder = LoadTestAdministrationClientBuilder.class, isAsync = true)
public final class LoadTestAdministrationAsyncClient {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Generated private final LoadTestAdministrationsImpl serviceClient;

    /**
     * Initializes an instance of LoadTestAdministrationAsyncClient class.
     *
     * @param serviceClient the service client implementation.
     */
    @Generated
    LoadTestAdministrationAsyncClient(LoadTestAdministrationsImpl serviceClient) {
        this.serviceClient = serviceClient;
    }

    /**
     * Configure server metrics for a test.
     *
     * <p><strong>Request Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     testId: String (Optional)
     *     metrics (Optional): {
     *         String (Optional): {
     *             id: String (Optional)
     *             resourceId: String (Required)
     *             metricNamespace: String (Required)
     *             displayDescription: String (Optional)
     *             name: String (Required)
     *             aggregation: String (Required)
     *             unit: String (Optional)
     *             resourceType: String (Required)
     *         }
     *     }
     *     createdDateTime: OffsetDateTime (Optional)
     *     createdBy: String (Optional)
     *     lastModifiedDateTime: OffsetDateTime (Optional)
     *     lastModifiedBy: String (Optional)
     * }
     * }</pre>
     *
     * <p><strong>Response Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     testId: String (Optional)
     *     metrics (Optional): {
     *         String (Optional): {
     *             id: String (Optional)
     *             resourceId: String (Required)
     *             metricNamespace: String (Required)
     *             displayDescription: String (Optional)
     *             name: String (Required)
     *             aggregation: String (Required)
     *             unit: String (Optional)
     *             resourceType: String (Required)
     *         }
     *     }
     *     createdDateTime: OffsetDateTime (Optional)
     *     createdBy: String (Optional)
     *     lastModifiedDateTime: OffsetDateTime (Optional)
     *     lastModifiedBy: String (Optional)
     * }
     * }</pre>
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param body Server metric configuration model.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return test server metrics configuration along with {@link Response} on successful completion of {@link Mono}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<BinaryData>> createOrUpdateServerMetricsConfigWithResponse(
            String testId, BinaryData body, RequestOptions requestOptions) {
        return this.serviceClient.createOrUpdateServerMetricsConfigWithResponseAsync(testId, body, requestOptions);
    }

    private Mono<PollResponse<BinaryData>> getValidationStatus(BinaryData fileBinary) {
        String validationStatus, fileType;
        JsonNode file;
        try {
            file = OBJECT_MAPPER.readTree(fileBinary.toString());
            validationStatus = file.get("validationStatus").asText();
            fileType = file.get("fileType").asText();
        } catch (JsonProcessingException e) {
            return Mono.error(new RuntimeException("Encountered exception while retrieving validation status", e));
        }
        LongRunningOperationStatus lroStatus;
        switch (validationStatus) {
            case "VALIDATION_NOT_REQUIRED":
            case "VALIDATION_SUCCESS":
                lroStatus = LongRunningOperationStatus.SUCCESSFULLY_COMPLETED;
                break;
            case "VALIDATION_FAILURE":
                lroStatus = LongRunningOperationStatus.FAILED;
                break;
            case "VALIDATION_INITIATED":
                lroStatus = LongRunningOperationStatus.IN_PROGRESS;
                break;
            case "NOT_VALIDATED":
                if ("JMX_FILE".equalsIgnoreCase(fileType)) {
                    lroStatus = LongRunningOperationStatus.NOT_STARTED;
                } else {
                    lroStatus = LongRunningOperationStatus.SUCCESSFULLY_COMPLETED;
                }
                break;
            default:
                lroStatus = LongRunningOperationStatus.NOT_STARTED;
                break;
        }
        return Mono.just(new PollResponse<>(lroStatus, fileBinary));
    }

    /**
     * Uploads file and polls the validation status of the uploaded file.
     *
     * @param testId Unique name for load test, must be a valid URL character ^[a-z0-9_-]*$.
     * @param fileName Unique name for test file with file extension like : App.jmx.
     * @param body The file content as application/octet-stream.
     * @param fileUploadRequestOptions The options to configure the file upload HTTP request before HTTP client sends
     *     it.
     * @throws ResourceNotFoundException when a test with {@code testId} doesn't exist.
     * @return A {@link PollerFlux} to poll on and retrieve the file info with validation status.
     */
    @ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION)
    public PollerFlux<BinaryData, BinaryData> beginUploadTestFile(
            String testId, String fileName, BinaryData body, RequestOptions fileUploadRequestOptions) {
        RequestOptions defaultRequestOptions = new RequestOptions();
        if (fileUploadRequestOptions != null) {
            defaultRequestOptions.setContext(fileUploadRequestOptions.getContext());
        }
        return new PollerFlux<>(
                Duration.ofSeconds(2),
                (context) -> {
                    Mono<BinaryData> fileMono =
                            uploadTestFileWithResponse(testId, fileName, body, fileUploadRequestOptions)
                                    .flatMap(FluxUtil::toMono);
                    Mono<PollResponse<BinaryData>> fileValidationPollRespMono =
                            fileMono.flatMap(fileBinaryData -> getValidationStatus(fileBinaryData));
                    return fileValidationPollRespMono.flatMap(
                            fileValidationPollResp -> Mono.just(fileValidationPollResp.getValue()));
                },
                (context) -> {
                    Mono<BinaryData> fileMono =
                            getTestFileWithResponse(testId, fileName, defaultRequestOptions).flatMap(FluxUtil::toMono);
                    return fileMono.flatMap(fileBinaryData -> getValidationStatus(fileBinaryData));
                },
                (activationResponse, context) -> Mono.error(new RuntimeException("Cancellation is not supported")),
                (context) ->
                        getTestFileWithResponse(testId, fileName, defaultRequestOptions).flatMap(FluxUtil::toMono));
    }

    /**
     * Get all test files.
     *
     * <p><strong>Response Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     value (Required): [
     *          (Required){
     *             url: String (Optional)
     *             fileName: String (Optional)
     *             fileType: String(JMX_FILE/USER_PROPERTIES/ADDITIONAL_ARTIFACTS) (Optional)
     *             expireDateTime: OffsetDateTime (Optional)
     *             validationStatus: String(NOT_VALIDATED/VALIDATION_SUCCESS/VALIDATION_FAILURE/VALIDATION_INITIATED/VALIDATION_NOT_REQUIRED) (Optional)
     *             validationFailureDetails: String (Optional)
     *         }
     *     ]
     *     nextLink: String (Optional)
     * }
     * }</pre>
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return all test files as paginated response with {@link PagedFlux}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<BinaryData> listTestFiles(String testId, RequestOptions requestOptions) {
        return this.serviceClient.listTestFilesAsync(testId, requestOptions);
    }

    /**
     * Create a new test or update an existing test.
     *
     * <p><strong>Request Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     passFailCriteria (Optional): {
     *         passFailMetrics (Optional): {
     *             String (Optional): {
     *                 clientMetric: String(response_time_ms/latency/error/requests/requests_per_sec) (Optional)
     *                 aggregate: String(count/percentage/avg/p50/p90/p95/p99/min/max) (Optional)
     *                 condition: String (Optional)
     *                 requestName: String (Optional)
     *                 value: Double (Optional)
     *                 action: String(continue/stop) (Optional)
     *                 actualValue: Double (Optional)
     *                 result: String(passed/undetermined/failed) (Optional)
     *             }
     *         }
     *     }
     *     secrets (Optional): {
     *         String (Optional): {
     *             value: String (Optional)
     *             type: String(AKV_SECRET_URI/SECRET_VALUE) (Optional)
     *         }
     *     }
     *     certificate (Optional): {
     *         value: String (Optional)
     *         type: String(AKV_CERT_URI) (Optional)
     *         name: String (Optional)
     *     }
     *     environmentVariables (Optional): {
     *         String: String (Optional)
     *     }
     *     loadTestConfiguration (Optional): {
     *         engineInstances: Integer (Optional)
     *         splitAllCSVs: Boolean (Optional)
     *         quickStartTest: Boolean (Optional)
     *         optionalLoadTestConfig (Optional): {
     *             endpointUrl: String (Optional)
     *             virtualUsers: Integer (Optional)
     *             rampUpTime: Integer (Optional)
     *             duration: Integer (Optional)
     *         }
     *     }
     *     inputArtifacts (Optional): {
     *         configFileInfo (Optional): {
     *             url: String (Optional)
     *             fileName: String (Optional)
     *             fileType: String(JMX_FILE/USER_PROPERTIES/ADDITIONAL_ARTIFACTS) (Optional)
     *             expireDateTime: OffsetDateTime (Optional)
     *             validationStatus: String(NOT_VALIDATED/VALIDATION_SUCCESS/VALIDATION_FAILURE/VALIDATION_INITIATED/VALIDATION_NOT_REQUIRED) (Optional)
     *             validationFailureDetails: String (Optional)
     *         }
     *         testScriptFileInfo (Optional): (recursive schema, see testScriptFileInfo above)
     *         userPropFileInfo (Optional): (recursive schema, see userPropFileInfo above)
     *         inputArtifactsZipFileInfo (Optional): (recursive schema, see inputArtifactsZipFileInfo above)
     *         additionalFileInfo (Optional): [
     *             (recursive schema, see above)
     *         ]
     *     }
     *     testId: String (Optional)
     *     description: String (Optional)
     *     displayName: String (Optional)
     *     subnetId: String (Optional)
     *     keyvaultReferenceIdentityType: String (Optional)
     *     keyvaultReferenceIdentityId: String (Optional)
     *     createdDateTime: OffsetDateTime (Optional)
     *     createdBy: String (Optional)
     *     lastModifiedDateTime: OffsetDateTime (Optional)
     *     lastModifiedBy: String (Optional)
     * }
     * }</pre>
     *
     * <p><strong>Response Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     passFailCriteria (Optional): {
     *         passFailMetrics (Optional): {
     *             String (Optional): {
     *                 clientMetric: String(response_time_ms/latency/error/requests/requests_per_sec) (Optional)
     *                 aggregate: String(count/percentage/avg/p50/p90/p95/p99/min/max) (Optional)
     *                 condition: String (Optional)
     *                 requestName: String (Optional)
     *                 value: Double (Optional)
     *                 action: String(continue/stop) (Optional)
     *                 actualValue: Double (Optional)
     *                 result: String(passed/undetermined/failed) (Optional)
     *             }
     *         }
     *     }
     *     secrets (Optional): {
     *         String (Optional): {
     *             value: String (Optional)
     *             type: String(AKV_SECRET_URI/SECRET_VALUE) (Optional)
     *         }
     *     }
     *     certificate (Optional): {
     *         value: String (Optional)
     *         type: String(AKV_CERT_URI) (Optional)
     *         name: String (Optional)
     *     }
     *     environmentVariables (Optional): {
     *         String: String (Optional)
     *     }
     *     loadTestConfiguration (Optional): {
     *         engineInstances: Integer (Optional)
     *         splitAllCSVs: Boolean (Optional)
     *         quickStartTest: Boolean (Optional)
     *         optionalLoadTestConfig (Optional): {
     *             endpointUrl: String (Optional)
     *             virtualUsers: Integer (Optional)
     *             rampUpTime: Integer (Optional)
     *             duration: Integer (Optional)
     *         }
     *     }
     *     inputArtifacts (Optional): {
     *         configFileInfo (Optional): {
     *             url: String (Optional)
     *             fileName: String (Optional)
     *             fileType: String(JMX_FILE/USER_PROPERTIES/ADDITIONAL_ARTIFACTS) (Optional)
     *             expireDateTime: OffsetDateTime (Optional)
     *             validationStatus: String(NOT_VALIDATED/VALIDATION_SUCCESS/VALIDATION_FAILURE/VALIDATION_INITIATED/VALIDATION_NOT_REQUIRED) (Optional)
     *             validationFailureDetails: String (Optional)
     *         }
     *         testScriptFileInfo (Optional): (recursive schema, see testScriptFileInfo above)
     *         userPropFileInfo (Optional): (recursive schema, see userPropFileInfo above)
     *         inputArtifactsZipFileInfo (Optional): (recursive schema, see inputArtifactsZipFileInfo above)
     *         additionalFileInfo (Optional): [
     *             (recursive schema, see above)
     *         ]
     *     }
     *     testId: String (Optional)
     *     description: String (Optional)
     *     displayName: String (Optional)
     *     subnetId: String (Optional)
     *     keyvaultReferenceIdentityType: String (Optional)
     *     keyvaultReferenceIdentityId: String (Optional)
     *     createdDateTime: OffsetDateTime (Optional)
     *     createdBy: String (Optional)
     *     lastModifiedDateTime: OffsetDateTime (Optional)
     *     lastModifiedBy: String (Optional)
     * }
     * }</pre>
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param body Load test model.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return load test model along with {@link Response} on successful completion of {@link Mono}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<BinaryData>> createOrUpdateTestWithResponse(
            String testId, BinaryData body, RequestOptions requestOptions) {
        return this.serviceClient.createOrUpdateTestWithResponseAsync(testId, body, requestOptions);
    }

    /**
     * Delete a test by its name.
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return the {@link Response} on successful completion of {@link Mono}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> deleteTestWithResponse(String testId, RequestOptions requestOptions) {
        return this.serviceClient.deleteTestWithResponseAsync(testId, requestOptions);
    }

    /**
     * Get load test details by test name.
     *
     * <p><strong>Response Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     passFailCriteria (Optional): {
     *         passFailMetrics (Optional): {
     *             String (Optional): {
     *                 clientMetric: String(response_time_ms/latency/error/requests/requests_per_sec) (Optional)
     *                 aggregate: String(count/percentage/avg/p50/p90/p95/p99/min/max) (Optional)
     *                 condition: String (Optional)
     *                 requestName: String (Optional)
     *                 value: Double (Optional)
     *                 action: String(continue/stop) (Optional)
     *                 actualValue: Double (Optional)
     *                 result: String(passed/undetermined/failed) (Optional)
     *             }
     *         }
     *     }
     *     secrets (Optional): {
     *         String (Optional): {
     *             value: String (Optional)
     *             type: String(AKV_SECRET_URI/SECRET_VALUE) (Optional)
     *         }
     *     }
     *     certificate (Optional): {
     *         value: String (Optional)
     *         type: String(AKV_CERT_URI) (Optional)
     *         name: String (Optional)
     *     }
     *     environmentVariables (Optional): {
     *         String: String (Optional)
     *     }
     *     loadTestConfiguration (Optional): {
     *         engineInstances: Integer (Optional)
     *         splitAllCSVs: Boolean (Optional)
     *         quickStartTest: Boolean (Optional)
     *         optionalLoadTestConfig (Optional): {
     *             endpointUrl: String (Optional)
     *             virtualUsers: Integer (Optional)
     *             rampUpTime: Integer (Optional)
     *             duration: Integer (Optional)
     *         }
     *     }
     *     inputArtifacts (Optional): {
     *         configFileInfo (Optional): {
     *             url: String (Optional)
     *             fileName: String (Optional)
     *             fileType: String(JMX_FILE/USER_PROPERTIES/ADDITIONAL_ARTIFACTS) (Optional)
     *             expireDateTime: OffsetDateTime (Optional)
     *             validationStatus: String(NOT_VALIDATED/VALIDATION_SUCCESS/VALIDATION_FAILURE/VALIDATION_INITIATED/VALIDATION_NOT_REQUIRED) (Optional)
     *             validationFailureDetails: String (Optional)
     *         }
     *         testScriptFileInfo (Optional): (recursive schema, see testScriptFileInfo above)
     *         userPropFileInfo (Optional): (recursive schema, see userPropFileInfo above)
     *         inputArtifactsZipFileInfo (Optional): (recursive schema, see inputArtifactsZipFileInfo above)
     *         additionalFileInfo (Optional): [
     *             (recursive schema, see above)
     *         ]
     *     }
     *     testId: String (Optional)
     *     description: String (Optional)
     *     displayName: String (Optional)
     *     subnetId: String (Optional)
     *     keyvaultReferenceIdentityType: String (Optional)
     *     keyvaultReferenceIdentityId: String (Optional)
     *     createdDateTime: OffsetDateTime (Optional)
     *     createdBy: String (Optional)
     *     lastModifiedDateTime: OffsetDateTime (Optional)
     *     lastModifiedBy: String (Optional)
     * }
     * }</pre>
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return load test details by test name along with {@link Response} on successful completion of {@link Mono}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<BinaryData>> getTestWithResponse(String testId, RequestOptions requestOptions) {
        return this.serviceClient.getTestWithResponseAsync(testId, requestOptions);
    }

    /**
     * Get all load tests by the fully qualified resource Id e.g
     * subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.LoadTestService/loadtests/{resName}.
     *
     * <p><strong>Query Parameters</strong>
     *
     * <table border="1">
     *     <caption>Query Parameters</caption>
     *     <tr><th>Name</th><th>Type</th><th>Required</th><th>Description</th></tr>
     *     <tr><td>orderby</td><td>String</td><td>No</td><td>Sort on the supported fields in (field asc/desc) format. eg: lastModifiedDateTime asc. Supported fields - lastModifiedDateTime</td></tr>
     *     <tr><td>search</td><td>String</td><td>No</td><td>Prefix based, case sensitive search on searchable fields - displayName, createdBy. For example, to search for a test, with display name is Login Test, the search parameter can be Login.</td></tr>
     *     <tr><td>lastModifiedStartTime</td><td>OffsetDateTime</td><td>No</td><td>Start DateTime(ISO 8601 literal format) of the last updated time range to filter tests.</td></tr>
     *     <tr><td>lastModifiedEndTime</td><td>OffsetDateTime</td><td>No</td><td>End DateTime(ISO 8601 literal format) of the last updated time range to filter tests.</td></tr>
     *     <tr><td>maxpagesize</td><td>Integer</td><td>No</td><td>Number of results in response.</td></tr>
     * </table>
     *
     * You can add these to a request with {@link RequestOptions#addQueryParam}
     *
     * <p><strong>Response Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     value (Required): [
     *          (Required){
     *             passFailCriteria (Optional): {
     *                 passFailMetrics (Optional): {
     *                     String (Optional): {
     *                         clientMetric: String(response_time_ms/latency/error/requests/requests_per_sec) (Optional)
     *                         aggregate: String(count/percentage/avg/p50/p90/p95/p99/min/max) (Optional)
     *                         condition: String (Optional)
     *                         requestName: String (Optional)
     *                         value: Double (Optional)
     *                         action: String(continue/stop) (Optional)
     *                         actualValue: Double (Optional)
     *                         result: String(passed/undetermined/failed) (Optional)
     *                     }
     *                 }
     *             }
     *             secrets (Optional): {
     *                 String (Optional): {
     *                     value: String (Optional)
     *                     type: String(AKV_SECRET_URI/SECRET_VALUE) (Optional)
     *                 }
     *             }
     *             certificate (Optional): {
     *                 value: String (Optional)
     *                 type: String(AKV_CERT_URI) (Optional)
     *                 name: String (Optional)
     *             }
     *             environmentVariables (Optional): {
     *                 String: String (Optional)
     *             }
     *             loadTestConfiguration (Optional): {
     *                 engineInstances: Integer (Optional)
     *                 splitAllCSVs: Boolean (Optional)
     *                 quickStartTest: Boolean (Optional)
     *                 optionalLoadTestConfig (Optional): {
     *                     endpointUrl: String (Optional)
     *                     virtualUsers: Integer (Optional)
     *                     rampUpTime: Integer (Optional)
     *                     duration: Integer (Optional)
     *                 }
     *             }
     *             inputArtifacts (Optional): {
     *                 configFileInfo (Optional): {
     *                     url: String (Optional)
     *                     fileName: String (Optional)
     *                     fileType: String(JMX_FILE/USER_PROPERTIES/ADDITIONAL_ARTIFACTS) (Optional)
     *                     expireDateTime: OffsetDateTime (Optional)
     *                     validationStatus: String(NOT_VALIDATED/VALIDATION_SUCCESS/VALIDATION_FAILURE/VALIDATION_INITIATED/VALIDATION_NOT_REQUIRED) (Optional)
     *                     validationFailureDetails: String (Optional)
     *                 }
     *                 testScriptFileInfo (Optional): (recursive schema, see testScriptFileInfo above)
     *                 userPropFileInfo (Optional): (recursive schema, see userPropFileInfo above)
     *                 inputArtifactsZipFileInfo (Optional): (recursive schema, see inputArtifactsZipFileInfo above)
     *                 additionalFileInfo (Optional): [
     *                     (recursive schema, see above)
     *                 ]
     *             }
     *             testId: String (Optional)
     *             description: String (Optional)
     *             displayName: String (Optional)
     *             subnetId: String (Optional)
     *             keyvaultReferenceIdentityType: String (Optional)
     *             keyvaultReferenceIdentityId: String (Optional)
     *             createdDateTime: OffsetDateTime (Optional)
     *             createdBy: String (Optional)
     *             lastModifiedDateTime: OffsetDateTime (Optional)
     *             lastModifiedBy: String (Optional)
     *         }
     *     ]
     *     nextLink: String (Optional)
     * }
     * }</pre>
     *
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return all load tests by the fully qualified resource Id e.g
     *     subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.LoadTestService/loadtests/{resName} as
     *     paginated response with {@link PagedFlux}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.COLLECTION)
    public PagedFlux<BinaryData> listTests(RequestOptions requestOptions) {
        return this.serviceClient.listTestsAsync(requestOptions);
    }

    /**
     * Upload input file for a given test name. File size can't be more than 50 MB. Existing file with same name for the
     * given test will be overwritten. File should be provided in the request body as application/octet-stream.
     *
     * <p><strong>Query Parameters</strong>
     *
     * <table border="1">
     *     <caption>Query Parameters</caption>
     *     <tr><th>Name</th><th>Type</th><th>Required</th><th>Description</th></tr>
     *     <tr><td>fileType</td><td>String</td><td>No</td><td>File type. Allowed values: "JMX_FILE", "USER_PROPERTIES", "ADDITIONAL_ARTIFACTS".</td></tr>
     * </table>
     *
     * You can add these to a request with {@link RequestOptions#addQueryParam}
     *
     * <p><strong>Request Body Schema</strong>
     *
     * <pre>{@code
     * BinaryData
     * }</pre>
     *
     * <p><strong>Response Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     url: String (Optional)
     *     fileName: String (Optional)
     *     fileType: String(JMX_FILE/USER_PROPERTIES/ADDITIONAL_ARTIFACTS) (Optional)
     *     expireDateTime: OffsetDateTime (Optional)
     *     validationStatus: String(NOT_VALIDATED/VALIDATION_SUCCESS/VALIDATION_FAILURE/VALIDATION_INITIATED/VALIDATION_NOT_REQUIRED) (Optional)
     *     validationFailureDetails: String (Optional)
     * }
     * }</pre>
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param fileName Unique name for test file with file extension like : App.jmx.
     * @param body The file content as application/octet-stream.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return file info along with {@link Response} on successful completion of {@link Mono}.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    Mono<Response<BinaryData>> uploadTestFileWithResponse(
            String testId, String fileName, BinaryData body, RequestOptions requestOptions) {
        return this.serviceClient.uploadTestFileWithResponseAsync(testId, fileName, body, requestOptions);
    }

    /**
     * Get test file by the file name.
     *
     * <p><strong>Response Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     url: String (Optional)
     *     fileName: String (Optional)
     *     fileType: String(JMX_FILE/USER_PROPERTIES/ADDITIONAL_ARTIFACTS) (Optional)
     *     expireDateTime: OffsetDateTime (Optional)
     *     validationStatus: String(NOT_VALIDATED/VALIDATION_SUCCESS/VALIDATION_FAILURE/VALIDATION_INITIATED/VALIDATION_NOT_REQUIRED) (Optional)
     *     validationFailureDetails: String (Optional)
     * }
     * }</pre>
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param fileName File name with file extension like app.jmx.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return test file by the file name along with {@link Response} on successful completion of {@link Mono}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<BinaryData>> getTestFileWithResponse(
            String testId, String fileName, RequestOptions requestOptions) {
        return this.serviceClient.getTestFileWithResponseAsync(testId, fileName, requestOptions);
    }

    /**
     * Delete file by the file name for a test.
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param fileName File name with file extension like app.jmx.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return the {@link Response} on successful completion of {@link Mono}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<Void>> deleteTestFileWithResponse(
            String testId, String fileName, RequestOptions requestOptions) {
        return this.serviceClient.deleteTestFileWithResponseAsync(testId, fileName, requestOptions);
    }

    /**
     * Associate an app component (collection of azure resources) to a test.
     *
     * <p><strong>Request Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     components (Required): {
     *         String (Required): {
     *             resourceId: String (Optional)
     *             resourceName: String (Optional)
     *             resourceType: String (Optional)
     *             displayName: String (Optional)
     *             resourceGroup: String (Optional)
     *             subscriptionId: String (Optional)
     *             kind: String (Optional)
     *         }
     *     }
     *     testId: String (Optional)
     *     createdDateTime: OffsetDateTime (Optional)
     *     createdBy: String (Optional)
     *     lastModifiedDateTime: OffsetDateTime (Optional)
     *     lastModifiedBy: String (Optional)
     * }
     * }</pre>
     *
     * <p><strong>Response Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     components (Required): {
     *         String (Required): {
     *             resourceId: String (Optional)
     *             resourceName: String (Optional)
     *             resourceType: String (Optional)
     *             displayName: String (Optional)
     *             resourceGroup: String (Optional)
     *             subscriptionId: String (Optional)
     *             kind: String (Optional)
     *         }
     *     }
     *     testId: String (Optional)
     *     createdDateTime: OffsetDateTime (Optional)
     *     createdBy: String (Optional)
     *     lastModifiedDateTime: OffsetDateTime (Optional)
     *     lastModifiedBy: String (Optional)
     * }
     * }</pre>
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param body App Component model.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return test app component along with {@link Response} on successful completion of {@link Mono}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<BinaryData>> createOrUpdateAppComponentsWithResponse(
            String testId, BinaryData body, RequestOptions requestOptions) {
        return this.serviceClient.createOrUpdateAppComponentsWithResponseAsync(testId, body, requestOptions);
    }

    /**
     * Get associated app component (collection of azure resources) for the given test.
     *
     * <p><strong>Response Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     components (Required): {
     *         String (Required): {
     *             resourceId: String (Optional)
     *             resourceName: String (Optional)
     *             resourceType: String (Optional)
     *             displayName: String (Optional)
     *             resourceGroup: String (Optional)
     *             subscriptionId: String (Optional)
     *             kind: String (Optional)
     *         }
     *     }
     *     testId: String (Optional)
     *     createdDateTime: OffsetDateTime (Optional)
     *     createdBy: String (Optional)
     *     lastModifiedDateTime: OffsetDateTime (Optional)
     *     lastModifiedBy: String (Optional)
     * }
     * }</pre>
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return associated app component (collection of azure resources) for the given test along with {@link Response}
     *     on successful completion of {@link Mono}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<BinaryData>> getAppComponentsWithResponse(String testId, RequestOptions requestOptions) {
        return this.serviceClient.getAppComponentsWithResponseAsync(testId, requestOptions);
    }

    /**
     * List server metrics configuration for the given test.
     *
     * <p><strong>Response Body Schema</strong>
     *
     * <pre>{@code
     * {
     *     testId: String (Optional)
     *     metrics (Optional): {
     *         String (Optional): {
     *             id: String (Optional)
     *             resourceId: String (Required)
     *             metricNamespace: String (Required)
     *             displayDescription: String (Optional)
     *             name: String (Required)
     *             aggregation: String (Required)
     *             unit: String (Optional)
     *             resourceType: String (Required)
     *         }
     *     }
     *     createdDateTime: OffsetDateTime (Optional)
     *     createdBy: String (Optional)
     *     lastModifiedDateTime: OffsetDateTime (Optional)
     *     lastModifiedBy: String (Optional)
     * }
     * }</pre>
     *
     * @param testId Unique name for the load test, must contain only lower-case alphabetic, numeric, underscore or
     *     hyphen characters.
     * @param requestOptions The options to configure the HTTP request before HTTP client sends it.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws ClientAuthenticationException thrown if the request is rejected by server on status code 401.
     * @throws ResourceNotFoundException thrown if the request is rejected by server on status code 404.
     * @throws ResourceModifiedException thrown if the request is rejected by server on status code 409.
     * @return test server metrics configuration along with {@link Response} on successful completion of {@link Mono}.
     */
    @Generated
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<BinaryData>> getServerMetricsConfigWithResponse(String testId, RequestOptions requestOptions) {
        return this.serviceClient.getServerMetricsConfigWithResponseAsync(testId, requestOptions);
    }
}
