/**
 * 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.management.edgegateway.v2019_03_01.implementation;

import retrofit2.Retrofit;
import com.google.common.reflect.TypeToken;
import com.microsoft.azure.AzureServiceFuture;
import com.microsoft.azure.CloudException;
import com.microsoft.azure.ListOperationCallback;
import com.microsoft.azure.Page;
import com.microsoft.azure.PagedList;
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 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.PUT;
import retrofit2.http.Query;
import retrofit2.http.Url;
import retrofit2.Response;
import rx.functions.Func1;
import rx.Observable;

/**
 * An instance of this class provides access to all the operations defined
 * in Triggers.
 */
public class TriggersInner {
    /** The Retrofit service to perform REST calls. */
    private TriggersService service;
    /** The service client containing this operation class. */
    private DataBoxEdgeManagementClientImpl client;

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

    /**
     * The interface defining all the services for Triggers to be
     * used by Retrofit to perform actually REST calls.
     */
    interface TriggersService {
        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.edgegateway.v2019_03_01.Triggers listByDataBoxEdgeDevice" })
        @GET("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DataBoxEdge/dataBoxEdgeDevices/{deviceName}/triggers")
        Observable<Response<ResponseBody>> listByDataBoxEdgeDevice(@Path("deviceName") String deviceName, @Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Query("api-version") String apiVersion, @Query("$expand") String expand, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.edgegateway.v2019_03_01.Triggers get" })
        @GET("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DataBoxEdge/dataBoxEdgeDevices/{deviceName}/triggers/{name}")
        Observable<Response<ResponseBody>> get(@Path("deviceName") String deviceName, @Path("name") String name, @Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.edgegateway.v2019_03_01.Triggers createOrUpdate" })
        @PUT("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DataBoxEdge/dataBoxEdgeDevices/{deviceName}/triggers/{name}")
        Observable<Response<ResponseBody>> createOrUpdate(@Path("deviceName") String deviceName, @Path("name") String name, @Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Body TriggerInner trigger, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.edgegateway.v2019_03_01.Triggers beginCreateOrUpdate" })
        @PUT("subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DataBoxEdge/dataBoxEdgeDevices/{deviceName}/triggers/{name}")
        Observable<Response<ResponseBody>> beginCreateOrUpdate(@Path("deviceName") String deviceName, @Path("name") String name, @Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Body TriggerInner trigger, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.edgegateway.v2019_03_01.Triggers delete" })
        @HTTP(path = "subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DataBoxEdge/dataBoxEdgeDevices/{deviceName}/triggers/{name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> delete(@Path("deviceName") String deviceName, @Path("name") String name, @Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.edgegateway.v2019_03_01.Triggers beginDelete" })
        @HTTP(path = "subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DataBoxEdge/dataBoxEdgeDevices/{deviceName}/triggers/{name}", method = "DELETE", hasBody = true)
        Observable<Response<ResponseBody>> beginDelete(@Path("deviceName") String deviceName, @Path("name") String name, @Path("subscriptionId") String subscriptionId, @Path("resourceGroupName") String resourceGroupName, @Query("api-version") String apiVersion, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: com.microsoft.azure.management.edgegateway.v2019_03_01.Triggers listByDataBoxEdgeDeviceNext" })
        @GET
        Observable<Response<ResponseBody>> listByDataBoxEdgeDeviceNext(@Url String nextUrl, @Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param deviceName The device name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;TriggerInner&gt; object if successful.
     */
    public PagedList<TriggerInner> listByDataBoxEdgeDevice(final String deviceName, final String resourceGroupName) {
        ServiceResponse<Page<TriggerInner>> response = listByDataBoxEdgeDeviceSinglePageAsync(deviceName, resourceGroupName).toBlocking().single();
        return new PagedList<TriggerInner>(response.body()) {
            @Override
            public Page<TriggerInner> nextPage(String nextPageLink) {
                return listByDataBoxEdgeDeviceNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param deviceName The device name.
     * @param resourceGroupName The resource group name.
     * @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<TriggerInner>> listByDataBoxEdgeDeviceAsync(final String deviceName, final String resourceGroupName, final ListOperationCallback<TriggerInner> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            listByDataBoxEdgeDeviceSinglePageAsync(deviceName, resourceGroupName),
            new Func1<String, Observable<ServiceResponse<Page<TriggerInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<TriggerInner>>> call(String nextPageLink) {
                    return listByDataBoxEdgeDeviceNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param deviceName The device name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;TriggerInner&gt; object
     */
    public Observable<Page<TriggerInner>> listByDataBoxEdgeDeviceAsync(final String deviceName, final String resourceGroupName) {
        return listByDataBoxEdgeDeviceWithServiceResponseAsync(deviceName, resourceGroupName)
            .map(new Func1<ServiceResponse<Page<TriggerInner>>, Page<TriggerInner>>() {
                @Override
                public Page<TriggerInner> call(ServiceResponse<Page<TriggerInner>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param deviceName The device name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;TriggerInner&gt; object
     */
    public Observable<ServiceResponse<Page<TriggerInner>>> listByDataBoxEdgeDeviceWithServiceResponseAsync(final String deviceName, final String resourceGroupName) {
        return listByDataBoxEdgeDeviceSinglePageAsync(deviceName, resourceGroupName)
            .concatMap(new Func1<ServiceResponse<Page<TriggerInner>>, Observable<ServiceResponse<Page<TriggerInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<TriggerInner>>> call(ServiceResponse<Page<TriggerInner>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listByDataBoxEdgeDeviceNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param deviceName The device name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;TriggerInner&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<TriggerInner>>> listByDataBoxEdgeDeviceSinglePageAsync(final String deviceName, final String resourceGroupName) {
        if (deviceName == null) {
            throw new IllegalArgumentException("Parameter deviceName is required and cannot be null.");
        }
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        final String expand = null;
        return service.listByDataBoxEdgeDevice(deviceName, this.client.subscriptionId(), resourceGroupName, this.client.apiVersion(), expand, this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<TriggerInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<TriggerInner>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<TriggerInner>> result = listByDataBoxEdgeDeviceDelegate(response);
                        return Observable.just(new ServiceResponse<Page<TriggerInner>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param deviceName The device name.
     * @param resourceGroupName The resource group name.
     * @param expand Specify $filter='CustomContextTag eq &lt;tag&gt;' to filter on custom context tag property
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;TriggerInner&gt; object if successful.
     */
    public PagedList<TriggerInner> listByDataBoxEdgeDevice(final String deviceName, final String resourceGroupName, final String expand) {
        ServiceResponse<Page<TriggerInner>> response = listByDataBoxEdgeDeviceSinglePageAsync(deviceName, resourceGroupName, expand).toBlocking().single();
        return new PagedList<TriggerInner>(response.body()) {
            @Override
            public Page<TriggerInner> nextPage(String nextPageLink) {
                return listByDataBoxEdgeDeviceNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param deviceName The device name.
     * @param resourceGroupName The resource group name.
     * @param expand Specify $filter='CustomContextTag eq &lt;tag&gt;' to filter on custom context tag property
     * @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<TriggerInner>> listByDataBoxEdgeDeviceAsync(final String deviceName, final String resourceGroupName, final String expand, final ListOperationCallback<TriggerInner> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            listByDataBoxEdgeDeviceSinglePageAsync(deviceName, resourceGroupName, expand),
            new Func1<String, Observable<ServiceResponse<Page<TriggerInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<TriggerInner>>> call(String nextPageLink) {
                    return listByDataBoxEdgeDeviceNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param deviceName The device name.
     * @param resourceGroupName The resource group name.
     * @param expand Specify $filter='CustomContextTag eq &lt;tag&gt;' to filter on custom context tag property
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;TriggerInner&gt; object
     */
    public Observable<Page<TriggerInner>> listByDataBoxEdgeDeviceAsync(final String deviceName, final String resourceGroupName, final String expand) {
        return listByDataBoxEdgeDeviceWithServiceResponseAsync(deviceName, resourceGroupName, expand)
            .map(new Func1<ServiceResponse<Page<TriggerInner>>, Page<TriggerInner>>() {
                @Override
                public Page<TriggerInner> call(ServiceResponse<Page<TriggerInner>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param deviceName The device name.
     * @param resourceGroupName The resource group name.
     * @param expand Specify $filter='CustomContextTag eq &lt;tag&gt;' to filter on custom context tag property
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;TriggerInner&gt; object
     */
    public Observable<ServiceResponse<Page<TriggerInner>>> listByDataBoxEdgeDeviceWithServiceResponseAsync(final String deviceName, final String resourceGroupName, final String expand) {
        return listByDataBoxEdgeDeviceSinglePageAsync(deviceName, resourceGroupName, expand)
            .concatMap(new Func1<ServiceResponse<Page<TriggerInner>>, Observable<ServiceResponse<Page<TriggerInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<TriggerInner>>> call(ServiceResponse<Page<TriggerInner>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listByDataBoxEdgeDeviceNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists all the triggers configured in the device.
     *
    ServiceResponse<PageImpl<TriggerInner>> * @param deviceName The device name.
    ServiceResponse<PageImpl<TriggerInner>> * @param resourceGroupName The resource group name.
    ServiceResponse<PageImpl<TriggerInner>> * @param expand Specify $filter='CustomContextTag eq &lt;tag&gt;' to filter on custom context tag property
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;TriggerInner&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<TriggerInner>>> listByDataBoxEdgeDeviceSinglePageAsync(final String deviceName, final String resourceGroupName, final String expand) {
        if (deviceName == null) {
            throw new IllegalArgumentException("Parameter deviceName is required and cannot be null.");
        }
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        return service.listByDataBoxEdgeDevice(deviceName, this.client.subscriptionId(), resourceGroupName, this.client.apiVersion(), expand, this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<TriggerInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<TriggerInner>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<TriggerInner>> result = listByDataBoxEdgeDeviceDelegate(response);
                        return Observable.just(new ServiceResponse<Page<TriggerInner>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Get a specific trigger by name.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the TriggerInner object if successful.
     */
    public TriggerInner get(String deviceName, String name, String resourceGroupName) {
        return getWithServiceResponseAsync(deviceName, name, resourceGroupName).toBlocking().single().body();
    }

    /**
     * Get a specific trigger by name.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @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<TriggerInner> getAsync(String deviceName, String name, String resourceGroupName, final ServiceCallback<TriggerInner> serviceCallback) {
        return ServiceFuture.fromResponse(getWithServiceResponseAsync(deviceName, name, resourceGroupName), serviceCallback);
    }

    /**
     * Get a specific trigger by name.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TriggerInner object
     */
    public Observable<TriggerInner> getAsync(String deviceName, String name, String resourceGroupName) {
        return getWithServiceResponseAsync(deviceName, name, resourceGroupName).map(new Func1<ServiceResponse<TriggerInner>, TriggerInner>() {
            @Override
            public TriggerInner call(ServiceResponse<TriggerInner> response) {
                return response.body();
            }
        });
    }

    /**
     * Get a specific trigger by name.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TriggerInner object
     */
    public Observable<ServiceResponse<TriggerInner>> getWithServiceResponseAsync(String deviceName, String name, String resourceGroupName) {
        if (deviceName == null) {
            throw new IllegalArgumentException("Parameter deviceName is required and cannot be null.");
        }
        if (name == null) {
            throw new IllegalArgumentException("Parameter name is required and cannot be null.");
        }
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        return service.get(deviceName, name, this.client.subscriptionId(), resourceGroupName, this.client.apiVersion(), this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<TriggerInner>>>() {
                @Override
                public Observable<ServiceResponse<TriggerInner>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<TriggerInner> clientResponse = getDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Creates or updates a trigger.
     *
     * @param deviceName Creates or updates a trigger
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @param trigger The trigger.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the TriggerInner object if successful.
     */
    public TriggerInner createOrUpdate(String deviceName, String name, String resourceGroupName, TriggerInner trigger) {
        return createOrUpdateWithServiceResponseAsync(deviceName, name, resourceGroupName, trigger).toBlocking().last().body();
    }

    /**
     * Creates or updates a trigger.
     *
     * @param deviceName Creates or updates a trigger
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @param trigger The trigger.
     * @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<TriggerInner> createOrUpdateAsync(String deviceName, String name, String resourceGroupName, TriggerInner trigger, final ServiceCallback<TriggerInner> serviceCallback) {
        return ServiceFuture.fromResponse(createOrUpdateWithServiceResponseAsync(deviceName, name, resourceGroupName, trigger), serviceCallback);
    }

    /**
     * Creates or updates a trigger.
     *
     * @param deviceName Creates or updates a trigger
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @param trigger The trigger.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable for the request
     */
    public Observable<TriggerInner> createOrUpdateAsync(String deviceName, String name, String resourceGroupName, TriggerInner trigger) {
        return createOrUpdateWithServiceResponseAsync(deviceName, name, resourceGroupName, trigger).map(new Func1<ServiceResponse<TriggerInner>, TriggerInner>() {
            @Override
            public TriggerInner call(ServiceResponse<TriggerInner> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates or updates a trigger.
     *
     * @param deviceName Creates or updates a trigger
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @param trigger The trigger.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable for the request
     */
    public Observable<ServiceResponse<TriggerInner>> createOrUpdateWithServiceResponseAsync(String deviceName, String name, String resourceGroupName, TriggerInner trigger) {
        if (deviceName == null) {
            throw new IllegalArgumentException("Parameter deviceName is required and cannot be null.");
        }
        if (name == null) {
            throw new IllegalArgumentException("Parameter name is required and cannot be null.");
        }
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (trigger == null) {
            throw new IllegalArgumentException("Parameter trigger is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        Validator.validate(trigger);
        Observable<Response<ResponseBody>> observable = service.createOrUpdate(deviceName, name, this.client.subscriptionId(), resourceGroupName, trigger, this.client.apiVersion(), this.client.acceptLanguage(), this.client.userAgent());
        return client.getAzureClient().getPutOrPatchResultAsync(observable, new TypeToken<TriggerInner>() { }.getType());
    }

    /**
     * Creates or updates a trigger.
     *
     * @param deviceName Creates or updates a trigger
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @param trigger The trigger.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the TriggerInner object if successful.
     */
    public TriggerInner beginCreateOrUpdate(String deviceName, String name, String resourceGroupName, TriggerInner trigger) {
        return beginCreateOrUpdateWithServiceResponseAsync(deviceName, name, resourceGroupName, trigger).toBlocking().single().body();
    }

    /**
     * Creates or updates a trigger.
     *
     * @param deviceName Creates or updates a trigger
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @param trigger The trigger.
     * @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<TriggerInner> beginCreateOrUpdateAsync(String deviceName, String name, String resourceGroupName, TriggerInner trigger, final ServiceCallback<TriggerInner> serviceCallback) {
        return ServiceFuture.fromResponse(beginCreateOrUpdateWithServiceResponseAsync(deviceName, name, resourceGroupName, trigger), serviceCallback);
    }

    /**
     * Creates or updates a trigger.
     *
     * @param deviceName Creates or updates a trigger
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @param trigger The trigger.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TriggerInner object
     */
    public Observable<TriggerInner> beginCreateOrUpdateAsync(String deviceName, String name, String resourceGroupName, TriggerInner trigger) {
        return beginCreateOrUpdateWithServiceResponseAsync(deviceName, name, resourceGroupName, trigger).map(new Func1<ServiceResponse<TriggerInner>, TriggerInner>() {
            @Override
            public TriggerInner call(ServiceResponse<TriggerInner> response) {
                return response.body();
            }
        });
    }

    /**
     * Creates or updates a trigger.
     *
     * @param deviceName Creates or updates a trigger
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @param trigger The trigger.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the TriggerInner object
     */
    public Observable<ServiceResponse<TriggerInner>> beginCreateOrUpdateWithServiceResponseAsync(String deviceName, String name, String resourceGroupName, TriggerInner trigger) {
        if (deviceName == null) {
            throw new IllegalArgumentException("Parameter deviceName is required and cannot be null.");
        }
        if (name == null) {
            throw new IllegalArgumentException("Parameter name is required and cannot be null.");
        }
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (trigger == null) {
            throw new IllegalArgumentException("Parameter trigger is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        Validator.validate(trigger);
        return service.beginCreateOrUpdate(deviceName, name, this.client.subscriptionId(), resourceGroupName, trigger, this.client.apiVersion(), this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<TriggerInner>>>() {
                @Override
                public Observable<ServiceResponse<TriggerInner>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<TriggerInner> clientResponse = beginCreateOrUpdateDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Deletes the trigger on the gateway device.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void delete(String deviceName, String name, String resourceGroupName) {
        deleteWithServiceResponseAsync(deviceName, name, resourceGroupName).toBlocking().last().body();
    }

    /**
     * Deletes the trigger on the gateway device.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @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<Void> deleteAsync(String deviceName, String name, String resourceGroupName, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromResponse(deleteWithServiceResponseAsync(deviceName, name, resourceGroupName), serviceCallback);
    }

    /**
     * Deletes the trigger on the gateway device.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable for the request
     */
    public Observable<Void> deleteAsync(String deviceName, String name, String resourceGroupName) {
        return deleteWithServiceResponseAsync(deviceName, name, resourceGroupName).map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes the trigger on the gateway device.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable for the request
     */
    public Observable<ServiceResponse<Void>> deleteWithServiceResponseAsync(String deviceName, String name, String resourceGroupName) {
        if (deviceName == null) {
            throw new IllegalArgumentException("Parameter deviceName is required and cannot be null.");
        }
        if (name == null) {
            throw new IllegalArgumentException("Parameter name is required and cannot be null.");
        }
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        Observable<Response<ResponseBody>> observable = service.delete(deviceName, name, this.client.subscriptionId(), resourceGroupName, this.client.apiVersion(), this.client.acceptLanguage(), this.client.userAgent());
        return client.getAzureClient().getPostOrDeleteResultAsync(observable, new TypeToken<Void>() { }.getType());
    }

    /**
     * Deletes the trigger on the gateway device.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     */
    public void beginDelete(String deviceName, String name, String resourceGroupName) {
        beginDeleteWithServiceResponseAsync(deviceName, name, resourceGroupName).toBlocking().single().body();
    }

    /**
     * Deletes the trigger on the gateway device.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @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<Void> beginDeleteAsync(String deviceName, String name, String resourceGroupName, final ServiceCallback<Void> serviceCallback) {
        return ServiceFuture.fromResponse(beginDeleteWithServiceResponseAsync(deviceName, name, resourceGroupName), serviceCallback);
    }

    /**
     * Deletes the trigger on the gateway device.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<Void> beginDeleteAsync(String deviceName, String name, String resourceGroupName) {
        return beginDeleteWithServiceResponseAsync(deviceName, name, resourceGroupName).map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Deletes the trigger on the gateway device.
     *
     * @param deviceName The device name.
     * @param name The trigger name.
     * @param resourceGroupName The resource group name.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<ServiceResponse<Void>> beginDeleteWithServiceResponseAsync(String deviceName, String name, String resourceGroupName) {
        if (deviceName == null) {
            throw new IllegalArgumentException("Parameter deviceName is required and cannot be null.");
        }
        if (name == null) {
            throw new IllegalArgumentException("Parameter name is required and cannot be null.");
        }
        if (this.client.subscriptionId() == null) {
            throw new IllegalArgumentException("Parameter this.client.subscriptionId() is required and cannot be null.");
        }
        if (resourceGroupName == null) {
            throw new IllegalArgumentException("Parameter resourceGroupName is required and cannot be null.");
        }
        if (this.client.apiVersion() == null) {
            throw new IllegalArgumentException("Parameter this.client.apiVersion() is required and cannot be null.");
        }
        return service.beginDelete(deviceName, name, this.client.subscriptionId(), resourceGroupName, this.client.apiVersion(), this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Void>>>() {
                @Override
                public Observable<ServiceResponse<Void>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<Void> clientResponse = beginDeleteDelegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

    /**
     * Lists all the triggers configured in the device.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws CloudException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the PagedList&lt;TriggerInner&gt; object if successful.
     */
    public PagedList<TriggerInner> listByDataBoxEdgeDeviceNext(final String nextPageLink) {
        ServiceResponse<Page<TriggerInner>> response = listByDataBoxEdgeDeviceNextSinglePageAsync(nextPageLink).toBlocking().single();
        return new PagedList<TriggerInner>(response.body()) {
            @Override
            public Page<TriggerInner> nextPage(String nextPageLink) {
                return listByDataBoxEdgeDeviceNextSinglePageAsync(nextPageLink).toBlocking().single().body();
            }
        };
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @param serviceFuture the ServiceFuture object tracking the Retrofit calls
     * @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<TriggerInner>> listByDataBoxEdgeDeviceNextAsync(final String nextPageLink, final ServiceFuture<List<TriggerInner>> serviceFuture, final ListOperationCallback<TriggerInner> serviceCallback) {
        return AzureServiceFuture.fromPageResponse(
            listByDataBoxEdgeDeviceNextSinglePageAsync(nextPageLink),
            new Func1<String, Observable<ServiceResponse<Page<TriggerInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<TriggerInner>>> call(String nextPageLink) {
                    return listByDataBoxEdgeDeviceNextSinglePageAsync(nextPageLink);
                }
            },
            serviceCallback);
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;TriggerInner&gt; object
     */
    public Observable<Page<TriggerInner>> listByDataBoxEdgeDeviceNextAsync(final String nextPageLink) {
        return listByDataBoxEdgeDeviceNextWithServiceResponseAsync(nextPageLink)
            .map(new Func1<ServiceResponse<Page<TriggerInner>>, Page<TriggerInner>>() {
                @Override
                public Page<TriggerInner> call(ServiceResponse<Page<TriggerInner>> response) {
                    return response.body();
                }
            });
    }

    /**
     * Lists all the triggers configured in the device.
     *
     * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the PagedList&lt;TriggerInner&gt; object
     */
    public Observable<ServiceResponse<Page<TriggerInner>>> listByDataBoxEdgeDeviceNextWithServiceResponseAsync(final String nextPageLink) {
        return listByDataBoxEdgeDeviceNextSinglePageAsync(nextPageLink)
            .concatMap(new Func1<ServiceResponse<Page<TriggerInner>>, Observable<ServiceResponse<Page<TriggerInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<TriggerInner>>> call(ServiceResponse<Page<TriggerInner>> page) {
                    String nextPageLink = page.body().nextPageLink();
                    if (nextPageLink == null) {
                        return Observable.just(page);
                    }
                    return Observable.just(page).concatWith(listByDataBoxEdgeDeviceNextWithServiceResponseAsync(nextPageLink));
                }
            });
    }

    /**
     * Lists all the triggers configured in the device.
     *
    ServiceResponse<PageImpl<TriggerInner>> * @param nextPageLink The NextLink from the previous successful call to List operation.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the PagedList&lt;TriggerInner&gt; object wrapped in {@link ServiceResponse} if successful.
     */
    public Observable<ServiceResponse<Page<TriggerInner>>> listByDataBoxEdgeDeviceNextSinglePageAsync(final String nextPageLink) {
        if (nextPageLink == null) {
            throw new IllegalArgumentException("Parameter nextPageLink is required and cannot be null.");
        }
        String nextUrl = String.format("%s", nextPageLink);
        return service.listByDataBoxEdgeDeviceNext(nextUrl, this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<ResponseBody>, Observable<ServiceResponse<Page<TriggerInner>>>>() {
                @Override
                public Observable<ServiceResponse<Page<TriggerInner>>> call(Response<ResponseBody> response) {
                    try {
                        ServiceResponse<PageImpl<TriggerInner>> result = listByDataBoxEdgeDeviceNextDelegate(response);
                        return Observable.just(new ServiceResponse<Page<TriggerInner>>(result.body(), result.response()));
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

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

}
