/**
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for
 * license information.
 *
 * Code generated by Microsoft (R) AutoRest Code Generator.
 */

package com.microsoft.azure.cognitiveservices.language.luis.authoring.implementation;

import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.AssignToAppOptionalParameter;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.GetAssignedOptionalParameter;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.RemoveFromAppOptionalParameter;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ListUserLUISAccountsOptionalParameter;
import retrofit2.Retrofit;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.AzureAccounts;
import com.google.common.base.Joiner;
import com.google.common.reflect.TypeToken;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.AzureAccountInfoObject;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.ErrorResponseException;
import com.microsoft.azure.cognitiveservices.language.luis.authoring.models.OperationStatus;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceFuture;
import com.microsoft.rest.ServiceResponse;
import com.microsoft.rest.Validator;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import okhttp3.ResponseBody;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.HTTP;
import retrofit2.http.Path;
import retrofit2.http.POST;
import retrofit2.Response;
import rx.functions.Func1;
import rx.Observable;

/**
 * An instance of this class provides access to all the operations defined
 * in AzureAccounts.
 */
public class AzureAccountsImpl implements AzureAccounts {
    /** The Retrofit service to perform REST calls. */
    private AzureAccountsService service;
    /** The service client containing this operation class. */
    private LUISAuthoringClientImpl client;

    /**
     * Initializes an instance of AzureAccountsImpl.
     *
     * @param retrofit the Retrofit instance built from a Retrofit Builder.
     * @param client the instance of the service client containing this operation class.
     */
    public AzureAccountsImpl(Retrofit retrofit, LUISAuthoringClientImpl client) {
        this.service = retrofit.create(AzureAccountsService.class);
        this.client = client;
    }

    /**
     * The interface defining all the services for AzureAccounts to be
     * used by Retrofit to perform actually REST calls.
     */
    interface AzureAccountsService {
        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.language.luis.authoring.AzureAccounts assignToApp" })
        @POST("apps/{appId}/azureaccounts")
        Observable<Response<ResponseBody>> assignToApp(@Path("appId") UUID appId, @Header("ArmToken") String armToken, @Body AzureAccountInfoObject azureAccountInfoObject, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.language.luis.authoring.AzureAccounts getAssigned" })
        @GET("apps/{appId}/azureaccounts")
        Observable<Response<ResponseBody>> getAssigned(@Path("appId") UUID appId, @Header("ArmToken") String armToken, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.language.luis.authoring.AzureAccounts removeFromApp" })
        @HTTP(path = "apps/{appId}/azureaccounts", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> removeFromApp(@Path("appId") UUID appId, @Header("ArmToken") String armToken, @Body AzureAccountInfoObject azureAccountInfoObject, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.cognitiveservices.language.luis.authoring.AzureAccounts listUserLUISAccounts" })
        @GET("azureaccounts")
        Observable<Response<ResponseBody>> listUserLUISAccounts(@Header("ArmToken") String armToken, @Header("accept-language") String acceptLanguage, @Header("x-ms-parameterized-host") String parameterizedHost, @Header("User-Agent") String userAgent);

    }


    /**
     * apps - Assign a LUIS Azure account to an application.
     * Assigns an Azure account to the application.
     *
     * @param appId The application ID.
     * @param assignToAppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the OperationStatus object if successful.
     */
    public OperationStatus assignToApp(UUID appId, AssignToAppOptionalParameter assignToAppOptionalParameter) {
        return assignToAppWithServiceResponseAsync(appId, assignToAppOptionalParameter).toBlocking().single().body();
    }

    /**
     * apps - Assign a LUIS Azure account to an application.
     * Assigns an Azure account to the application.
     *
     * @param appId The application ID.
     * @param assignToAppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<OperationStatus> assignToAppAsync(UUID appId, AssignToAppOptionalParameter assignToAppOptionalParameter, final ServiceCallback<OperationStatus> serviceCallback) {
        return ServiceFuture.fromResponse(assignToAppWithServiceResponseAsync(appId, assignToAppOptionalParameter), serviceCallback);
    }

    /**
     * apps - Assign a LUIS Azure account to an application.
     * Assigns an Azure account to the application.
     *
     * @param appId The application ID.
     * @param assignToAppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<OperationStatus> assignToAppAsync(UUID appId, AssignToAppOptionalParameter assignToAppOptionalParameter) {
        return assignToAppWithServiceResponseAsync(appId, assignToAppOptionalParameter).map(new Func1<ServiceResponse<OperationStatus>, OperationStatus>() {
            @Override
            public OperationStatus call(ServiceResponse<OperationStatus> response) {
                return response.body();
            }
        });
    }

    /**
     * apps - Assign a LUIS Azure account to an application.
     * Assigns an Azure account to the application.
     *
     * @param appId The application ID.
     * @param assignToAppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<ServiceResponse<OperationStatus>> assignToAppWithServiceResponseAsync(UUID appId, AssignToAppOptionalParameter assignToAppOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        final String armToken = assignToAppOptionalParameter != null ? assignToAppOptionalParameter.armToken() : null;
        final AzureAccountInfoObject azureAccountInfoObject = assignToAppOptionalParameter != null ? assignToAppOptionalParameter.azureAccountInfoObject() : null;

        return assignToAppWithServiceResponseAsync(appId, armToken, azureAccountInfoObject);
    }

    /**
     * apps - Assign a LUIS Azure account to an application.
     * Assigns an Azure account to the application.
     *
     * @param appId The application ID.
     * @param armToken The custom arm token header to use; containing the user's ARM token used to validate azure accounts information.
     * @param azureAccountInfoObject The Azure account information object.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<ServiceResponse<OperationStatus>> assignToAppWithServiceResponseAsync(UUID appId, String armToken, AzureAccountInfoObject azureAccountInfoObject) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        Validator.validate(azureAccountInfoObject);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.assignToApp(appId, armToken, azureAccountInfoObject, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<OperationStatus>>>() {
                @Override
                public Observable<ServiceResponse<OperationStatus>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<OperationStatus> clientResponse = assignToAppDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<OperationStatus> assignToAppDelegate(Response<ResponseBody> response) throws ErrorResponseException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<OperationStatus, ErrorResponseException>newInstance(this.client.serializerAdapter())
                .register(201, new TypeToken<OperationStatus>() { }.getType())
                .registerError(ErrorResponseException.class)
                .build(response);
    }

    @Override
    public AzureAccountsAssignToAppParameters assignToApp() {
        return new AzureAccountsAssignToAppParameters(this);
    }

    /**
     * Internal class implementing AzureAccountsAssignToAppDefinition.
     */
    class AzureAccountsAssignToAppParameters implements AzureAccountsAssignToAppDefinition {
        private AzureAccountsImpl parent;
        private UUID appId;
        private String armToken;
        private AzureAccountInfoObject azureAccountInfoObject;

        /**
         * Constructor.
         * @param parent the parent object.
         */
        AzureAccountsAssignToAppParameters(AzureAccountsImpl parent) {
            this.parent = parent;
        }

        @Override
        public AzureAccountsAssignToAppParameters withAppId(UUID appId) {
            this.appId = appId;
            return this;
        }

        @Override
        public AzureAccountsAssignToAppParameters withArmToken(String armToken) {
            this.armToken = armToken;
            return this;
        }

        @Override
        public AzureAccountsAssignToAppParameters withAzureAccountInfoObject(AzureAccountInfoObject azureAccountInfoObject) {
            this.azureAccountInfoObject = azureAccountInfoObject;
            return this;
        }

        @Override
        public OperationStatus execute() {
        return assignToAppWithServiceResponseAsync(appId, armToken, azureAccountInfoObject).toBlocking().single().body();
    }

        @Override
        public Observable<OperationStatus> executeAsync() {
            return assignToAppWithServiceResponseAsync(appId, armToken, azureAccountInfoObject).map(new Func1<ServiceResponse<OperationStatus>, OperationStatus>() {
                @Override
                public OperationStatus call(ServiceResponse<OperationStatus> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * apps - Get LUIS Azure accounts assigned to the application.
     * Gets the LUIS Azure accounts assigned to the application for the user using his ARM token.
     *
     * @param appId The application ID.
     * @param getAssignedOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the List&lt;AzureAccountInfoObject&gt; object if successful.
     */
    public List<AzureAccountInfoObject> getAssigned(UUID appId, GetAssignedOptionalParameter getAssignedOptionalParameter) {
        return getAssignedWithServiceResponseAsync(appId, getAssignedOptionalParameter).toBlocking().single().body();
    }

    /**
     * apps - Get LUIS Azure accounts assigned to the application.
     * Gets the LUIS Azure accounts assigned to the application for the user using his ARM token.
     *
     * @param appId The application ID.
     * @param getAssignedOptionalParameter the object representing the optional parameters to be set before calling this API
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<AzureAccountInfoObject>> getAssignedAsync(UUID appId, GetAssignedOptionalParameter getAssignedOptionalParameter, final ServiceCallback<List<AzureAccountInfoObject>> serviceCallback) {
        return ServiceFuture.fromResponse(getAssignedWithServiceResponseAsync(appId, getAssignedOptionalParameter), serviceCallback);
    }

    /**
     * apps - Get LUIS Azure accounts assigned to the application.
     * Gets the LUIS Azure accounts assigned to the application for the user using his ARM token.
     *
     * @param appId The application ID.
     * @param getAssignedOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;AzureAccountInfoObject&gt; object
     */
    public Observable<List<AzureAccountInfoObject>> getAssignedAsync(UUID appId, GetAssignedOptionalParameter getAssignedOptionalParameter) {
        return getAssignedWithServiceResponseAsync(appId, getAssignedOptionalParameter).map(new Func1<ServiceResponse<List<AzureAccountInfoObject>>, List<AzureAccountInfoObject>>() {
            @Override
            public List<AzureAccountInfoObject> call(ServiceResponse<List<AzureAccountInfoObject>> response) {
                return response.body();
            }
        });
    }

    /**
     * apps - Get LUIS Azure accounts assigned to the application.
     * Gets the LUIS Azure accounts assigned to the application for the user using his ARM token.
     *
     * @param appId The application ID.
     * @param getAssignedOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;AzureAccountInfoObject&gt; object
     */
    public Observable<ServiceResponse<List<AzureAccountInfoObject>>> getAssignedWithServiceResponseAsync(UUID appId, GetAssignedOptionalParameter getAssignedOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        final String armToken = getAssignedOptionalParameter != null ? getAssignedOptionalParameter.armToken() : null;

        return getAssignedWithServiceResponseAsync(appId, armToken);
    }

    /**
     * apps - Get LUIS Azure accounts assigned to the application.
     * Gets the LUIS Azure accounts assigned to the application for the user using his ARM token.
     *
     * @param appId The application ID.
     * @param armToken The custom arm token header to use; containing the user's ARM token used to validate azure accounts information.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;AzureAccountInfoObject&gt; object
     */
    public Observable<ServiceResponse<List<AzureAccountInfoObject>>> getAssignedWithServiceResponseAsync(UUID appId, String armToken) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.getAssigned(appId, armToken, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<List<AzureAccountInfoObject>>>>() {
                @Override
                public Observable<ServiceResponse<List<AzureAccountInfoObject>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<List<AzureAccountInfoObject>> clientResponse = getAssignedDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<List<AzureAccountInfoObject>> getAssignedDelegate(Response<ResponseBody> response) throws ErrorResponseException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<List<AzureAccountInfoObject>, ErrorResponseException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<List<AzureAccountInfoObject>>() { }.getType())
                .registerError(ErrorResponseException.class)
                .build(response);
    }

    @Override
    public AzureAccountsGetAssignedParameters getAssigned() {
        return new AzureAccountsGetAssignedParameters(this);
    }

    /**
     * Internal class implementing AzureAccountsGetAssignedDefinition.
     */
    class AzureAccountsGetAssignedParameters implements AzureAccountsGetAssignedDefinition {
        private AzureAccountsImpl parent;
        private UUID appId;
        private String armToken;

        /**
         * Constructor.
         * @param parent the parent object.
         */
        AzureAccountsGetAssignedParameters(AzureAccountsImpl parent) {
            this.parent = parent;
        }

        @Override
        public AzureAccountsGetAssignedParameters withAppId(UUID appId) {
            this.appId = appId;
            return this;
        }

        @Override
        public AzureAccountsGetAssignedParameters withArmToken(String armToken) {
            this.armToken = armToken;
            return this;
        }

        @Override
        public List<AzureAccountInfoObject> execute() {
        return getAssignedWithServiceResponseAsync(appId, armToken).toBlocking().single().body();
    }

        @Override
        public Observable<List<AzureAccountInfoObject>> executeAsync() {
            return getAssignedWithServiceResponseAsync(appId, armToken).map(new Func1<ServiceResponse<List<AzureAccountInfoObject>>, List<AzureAccountInfoObject>>() {
                @Override
                public List<AzureAccountInfoObject> call(ServiceResponse<List<AzureAccountInfoObject>> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * apps - Removes an assigned LUIS Azure account from an application.
     * Removes assigned Azure account from the application.
     *
     * @param appId The application ID.
     * @param removeFromAppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the OperationStatus object if successful.
     */
    public OperationStatus removeFromApp(UUID appId, RemoveFromAppOptionalParameter removeFromAppOptionalParameter) {
        return removeFromAppWithServiceResponseAsync(appId, removeFromAppOptionalParameter).toBlocking().single().body();
    }

    /**
     * apps - Removes an assigned LUIS Azure account from an application.
     * Removes assigned Azure account from the application.
     *
     * @param appId The application ID.
     * @param removeFromAppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<OperationStatus> removeFromAppAsync(UUID appId, RemoveFromAppOptionalParameter removeFromAppOptionalParameter, final ServiceCallback<OperationStatus> serviceCallback) {
        return ServiceFuture.fromResponse(removeFromAppWithServiceResponseAsync(appId, removeFromAppOptionalParameter), serviceCallback);
    }

    /**
     * apps - Removes an assigned LUIS Azure account from an application.
     * Removes assigned Azure account from the application.
     *
     * @param appId The application ID.
     * @param removeFromAppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<OperationStatus> removeFromAppAsync(UUID appId, RemoveFromAppOptionalParameter removeFromAppOptionalParameter) {
        return removeFromAppWithServiceResponseAsync(appId, removeFromAppOptionalParameter).map(new Func1<ServiceResponse<OperationStatus>, OperationStatus>() {
            @Override
            public OperationStatus call(ServiceResponse<OperationStatus> response) {
                return response.body();
            }
        });
    }

    /**
     * apps - Removes an assigned LUIS Azure account from an application.
     * Removes assigned Azure account from the application.
     *
     * @param appId The application ID.
     * @param removeFromAppOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<ServiceResponse<OperationStatus>> removeFromAppWithServiceResponseAsync(UUID appId, RemoveFromAppOptionalParameter removeFromAppOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        final String armToken = removeFromAppOptionalParameter != null ? removeFromAppOptionalParameter.armToken() : null;
        final AzureAccountInfoObject azureAccountInfoObject = removeFromAppOptionalParameter != null ? removeFromAppOptionalParameter.azureAccountInfoObject() : null;

        return removeFromAppWithServiceResponseAsync(appId, armToken, azureAccountInfoObject);
    }

    /**
     * apps - Removes an assigned LUIS Azure account from an application.
     * Removes assigned Azure account from the application.
     *
     * @param appId The application ID.
     * @param armToken The custom arm token header to use; containing the user's ARM token used to validate azure accounts information.
     * @param azureAccountInfoObject The Azure account information object.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the OperationStatus object
     */
    public Observable<ServiceResponse<OperationStatus>> removeFromAppWithServiceResponseAsync(UUID appId, String armToken, AzureAccountInfoObject azureAccountInfoObject) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        if (appId == null) {
            throw new IllegalArgumentException("Parameter appId is required and cannot be null.");
        }
        Validator.validate(azureAccountInfoObject);
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.removeFromApp(appId, armToken, azureAccountInfoObject, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<OperationStatus>>>() {
                @Override
                public Observable<ServiceResponse<OperationStatus>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<OperationStatus> clientResponse = removeFromAppDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<OperationStatus> removeFromAppDelegate(Response<ResponseBody> response) throws ErrorResponseException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<OperationStatus, ErrorResponseException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<OperationStatus>() { }.getType())
                .registerError(ErrorResponseException.class)
                .build(response);
    }

    @Override
    public AzureAccountsRemoveFromAppParameters removeFromApp() {
        return new AzureAccountsRemoveFromAppParameters(this);
    }

    /**
     * Internal class implementing AzureAccountsRemoveFromAppDefinition.
     */
    class AzureAccountsRemoveFromAppParameters implements AzureAccountsRemoveFromAppDefinition {
        private AzureAccountsImpl parent;
        private UUID appId;
        private String armToken;
        private AzureAccountInfoObject azureAccountInfoObject;

        /**
         * Constructor.
         * @param parent the parent object.
         */
        AzureAccountsRemoveFromAppParameters(AzureAccountsImpl parent) {
            this.parent = parent;
        }

        @Override
        public AzureAccountsRemoveFromAppParameters withAppId(UUID appId) {
            this.appId = appId;
            return this;
        }

        @Override
        public AzureAccountsRemoveFromAppParameters withArmToken(String armToken) {
            this.armToken = armToken;
            return this;
        }

        @Override
        public AzureAccountsRemoveFromAppParameters withAzureAccountInfoObject(AzureAccountInfoObject azureAccountInfoObject) {
            this.azureAccountInfoObject = azureAccountInfoObject;
            return this;
        }

        @Override
        public OperationStatus execute() {
        return removeFromAppWithServiceResponseAsync(appId, armToken, azureAccountInfoObject).toBlocking().single().body();
    }

        @Override
        public Observable<OperationStatus> executeAsync() {
            return removeFromAppWithServiceResponseAsync(appId, armToken, azureAccountInfoObject).map(new Func1<ServiceResponse<OperationStatus>, OperationStatus>() {
                @Override
                public OperationStatus call(ServiceResponse<OperationStatus> response) {
                    return response.body();
                }
            });
        }
    }


    /**
     * user - Get LUIS Azure accounts.
     * Gets the LUIS Azure accounts for the user using his ARM token.
     *
     * @param listUserLUISAccountsOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws ErrorResponseException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the List&lt;AzureAccountInfoObject&gt; object if successful.
     */
    public List<AzureAccountInfoObject> listUserLUISAccounts(ListUserLUISAccountsOptionalParameter listUserLUISAccountsOptionalParameter) {
        return listUserLUISAccountsWithServiceResponseAsync(listUserLUISAccountsOptionalParameter).toBlocking().single().body();
    }

    /**
     * user - Get LUIS Azure accounts.
     * Gets the LUIS Azure accounts for the user using his ARM token.
     *
     * @param listUserLUISAccountsOptionalParameter the object representing the optional parameters to be set before calling this API
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceFuture} object
     */
    public ServiceFuture<List<AzureAccountInfoObject>> listUserLUISAccountsAsync(ListUserLUISAccountsOptionalParameter listUserLUISAccountsOptionalParameter, final ServiceCallback<List<AzureAccountInfoObject>> serviceCallback) {
        return ServiceFuture.fromResponse(listUserLUISAccountsWithServiceResponseAsync(listUserLUISAccountsOptionalParameter), serviceCallback);
    }

    /**
     * user - Get LUIS Azure accounts.
     * Gets the LUIS Azure accounts for the user using his ARM token.
     *
     * @param listUserLUISAccountsOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;AzureAccountInfoObject&gt; object
     */
    public Observable<List<AzureAccountInfoObject>> listUserLUISAccountsAsync(ListUserLUISAccountsOptionalParameter listUserLUISAccountsOptionalParameter) {
        return listUserLUISAccountsWithServiceResponseAsync(listUserLUISAccountsOptionalParameter).map(new Func1<ServiceResponse<List<AzureAccountInfoObject>>, List<AzureAccountInfoObject>>() {
            @Override
            public List<AzureAccountInfoObject> call(ServiceResponse<List<AzureAccountInfoObject>> response) {
                return response.body();
            }
        });
    }

    /**
     * user - Get LUIS Azure accounts.
     * Gets the LUIS Azure accounts for the user using his ARM token.
     *
     * @param listUserLUISAccountsOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;AzureAccountInfoObject&gt; object
     */
    public Observable<ServiceResponse<List<AzureAccountInfoObject>>> listUserLUISAccountsWithServiceResponseAsync(ListUserLUISAccountsOptionalParameter listUserLUISAccountsOptionalParameter) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        final String armToken = listUserLUISAccountsOptionalParameter != null ? listUserLUISAccountsOptionalParameter.armToken() : null;

        return listUserLUISAccountsWithServiceResponseAsync(armToken);
    }

    /**
     * user - Get LUIS Azure accounts.
     * Gets the LUIS Azure accounts for the user using his ARM token.
     *
     * @param armToken The custom arm token header to use; containing the user's ARM token used to validate azure accounts information.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the List&lt;AzureAccountInfoObject&gt; object
     */
    public Observable<ServiceResponse<List<AzureAccountInfoObject>>> listUserLUISAccountsWithServiceResponseAsync(String armToken) {
        if (this.client.endpoint() == null) {
            throw new IllegalArgumentException("Parameter this.client.endpoint() is required and cannot be null.");
        }
        String parameterizedHost = Joiner.on(", ").join("{Endpoint}", this.client.endpoint());
        return service.listUserLUISAccounts(armToken, this.client.acceptLanguage(), parameterizedHost, this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<List<AzureAccountInfoObject>>>>() {
                @Override
                public Observable<ServiceResponse<List<AzureAccountInfoObject>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<List<AzureAccountInfoObject>> clientResponse = listUserLUISAccountsDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<List<AzureAccountInfoObject>> listUserLUISAccountsDelegate(Response<ResponseBody> response) throws ErrorResponseException, IOException, IllegalArgumentException {
        return this.client.restClient().responseBuilderFactory().<List<AzureAccountInfoObject>, ErrorResponseException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<List<AzureAccountInfoObject>>() { }.getType())
                .registerError(ErrorResponseException.class)
                .build(response);
    }

    @Override
    public AzureAccountsListUserLUISAccountsParameters listUserLUISAccounts() {
        return new AzureAccountsListUserLUISAccountsParameters(this);
    }

    /**
     * Internal class implementing AzureAccountsListUserLUISAccountsDefinition.
     */
    class AzureAccountsListUserLUISAccountsParameters implements AzureAccountsListUserLUISAccountsDefinition {
        private AzureAccountsImpl parent;
        private String armToken;

        /**
         * Constructor.
         * @param parent the parent object.
         */
        AzureAccountsListUserLUISAccountsParameters(AzureAccountsImpl parent) {
            this.parent = parent;
        }

        @Override
        public AzureAccountsListUserLUISAccountsParameters withArmToken(String armToken) {
            this.armToken = armToken;
            return this;
        }

        @Override
        public List<AzureAccountInfoObject> execute() {
        return listUserLUISAccountsWithServiceResponseAsync(armToken).toBlocking().single().body();
    }

        @Override
        public Observable<List<AzureAccountInfoObject>> executeAsync() {
            return listUserLUISAccountsWithServiceResponseAsync(armToken).map(new Func1<ServiceResponse<List<AzureAccountInfoObject>>, List<AzureAccountInfoObject>>() {
                @Override
                public List<AzureAccountInfoObject> call(ServiceResponse<List<AzureAccountInfoObject>> response) {
                    return response.body();
                }
            });
        }
    }

}
