/**
 * 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.
 * Changes may cause incorrect behavior and will be lost if the code is
 * regenerated.
 */

package fixtures.headexceptions.implementation;

import retrofit2.Retrofit;
import com.google.common.reflect.TypeToken;
import com.microsoft.azure.CloudException;
import com.microsoft.rest.ServiceCall;
import com.microsoft.rest.ServiceCallback;
import com.microsoft.rest.ServiceResponse;
import java.io.IOException;
import retrofit2.http.HEAD;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.Response;
import rx.functions.Func1;
import rx.Observable;

/**
 * An instance of this class provides access to all the operations defined
 * in HeadExceptions.
 */
public class HeadExceptionsInner {
    /** The Retrofit service to perform REST calls. */
    private HeadExceptionsService service;
    /** The service client containing this operation class. */
    private AutoRestHeadExceptionTestServiceImpl client;

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

    /**
     * The interface defining all the services for HeadExceptions to be
     * used by Retrofit to perform actually REST calls.
     */
    interface HeadExceptionsService {
        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: fixtures.headexceptions.HeadExceptions head200" })
        @HEAD("http/success/200")
        Observable<Response<Void>> head200(@Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: fixtures.headexceptions.HeadExceptions head204" })
        @HEAD("http/success/204")
        Observable<Response<Void>> head204(@Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

        @Headers({ "Content-Type: application/json; charset=utf-8", "x-ms-logging-context: fixtures.headexceptions.HeadExceptions head404" })
        @HEAD("http/success/404")
        Observable<Response<Void>> head404(@Header("accept-language") String acceptLanguage, @Header("User-Agent") String userAgent);

    }

    /**
     * Return 200 status code if successful.
     *
     */
    public void head200() {
        head200WithServiceResponseAsync().toBlocking().single().body();
    }

    /**
     * Return 200 status code if successful.
     *
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @return the {@link ServiceCall} object
     */
    public ServiceCall<Void> head200Async(final ServiceCallback<Void> serviceCallback) {
        return ServiceCall.fromResponse(head200WithServiceResponseAsync(), serviceCallback);
    }

    /**
     * Return 200 status code if successful.
     *
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<Void> head200Async() {
        return head200WithServiceResponseAsync().map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Return 200 status code if successful.
     *
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<ServiceResponse<Void>> head200WithServiceResponseAsync() {
        return service.head200(this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<Void>, Observable<ServiceResponse<Void>>>() {
                @Override
                public Observable<ServiceResponse<Void>> call(Response<Void> response) {
                    try {
                        ServiceResponse<Void> clientResponse = head200Delegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Void> head200Delegate(Response<Void> response) throws CloudException, IOException {
        return this.client.restClient().responseBuilderFactory().<Void, CloudException>newInstance(this.client.serializerAdapter())
                .register(200, new TypeToken<Void>() { }.getType())
                .buildEmpty(response);
    }

    /**
     * Return 204 status code if successful.
     *
     */
    public void head204() {
        head204WithServiceResponseAsync().toBlocking().single().body();
    }

    /**
     * Return 204 status code if successful.
     *
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @return the {@link ServiceCall} object
     */
    public ServiceCall<Void> head204Async(final ServiceCallback<Void> serviceCallback) {
        return ServiceCall.fromResponse(head204WithServiceResponseAsync(), serviceCallback);
    }

    /**
     * Return 204 status code if successful.
     *
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<Void> head204Async() {
        return head204WithServiceResponseAsync().map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Return 204 status code if successful.
     *
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<ServiceResponse<Void>> head204WithServiceResponseAsync() {
        return service.head204(this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<Void>, Observable<ServiceResponse<Void>>>() {
                @Override
                public Observable<ServiceResponse<Void>> call(Response<Void> response) {
                    try {
                        ServiceResponse<Void> clientResponse = head204Delegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Void> head204Delegate(Response<Void> response) throws CloudException, IOException {
        return this.client.restClient().responseBuilderFactory().<Void, CloudException>newInstance(this.client.serializerAdapter())
                .register(204, new TypeToken<Void>() { }.getType())
                .buildEmpty(response);
    }

    /**
     * Return 404 status code if successful.
     *
     */
    public void head404() {
        head404WithServiceResponseAsync().toBlocking().single().body();
    }

    /**
     * Return 404 status code if successful.
     *
     * @param serviceCallback the async ServiceCallback to handle successful and failed responses.
     * @return the {@link ServiceCall} object
     */
    public ServiceCall<Void> head404Async(final ServiceCallback<Void> serviceCallback) {
        return ServiceCall.fromResponse(head404WithServiceResponseAsync(), serviceCallback);
    }

    /**
     * Return 404 status code if successful.
     *
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<Void> head404Async() {
        return head404WithServiceResponseAsync().map(new Func1<ServiceResponse<Void>, Void>() {
            @Override
            public Void call(ServiceResponse<Void> response) {
                return response.body();
            }
        });
    }

    /**
     * Return 404 status code if successful.
     *
     * @return the {@link ServiceResponse} object if successful.
     */
    public Observable<ServiceResponse<Void>> head404WithServiceResponseAsync() {
        return service.head404(this.client.acceptLanguage(), this.client.userAgent())
            .flatMap(new Func1<Response<Void>, Observable<ServiceResponse<Void>>>() {
                @Override
                public Observable<ServiceResponse<Void>> call(Response<Void> response) {
                    try {
                        ServiceResponse<Void> clientResponse = head404Delegate(response);
                        return Observable.just(clientResponse);
                    } catch (Throwable t) {
                        return Observable.error(t);
                    }
                }
            });
    }

    private ServiceResponse<Void> head404Delegate(Response<Void> response) throws CloudException, IOException {
        return this.client.restClient().responseBuilderFactory().<Void, CloudException>newInstance(this.client.serializerAdapter())
                .register(204, new TypeToken<Void>() { }.getType())
                .buildEmpty(response);
    }

}
