// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.maps.geolocation;

import com.azure.core.annotation.ReturnType;
import com.azure.core.annotation.ServiceClient;
import com.azure.core.annotation.ServiceMethod;
import com.azure.core.exception.HttpResponseException;
import com.azure.core.http.rest.Response;
import com.azure.core.util.Context;
import com.azure.maps.geolocation.implementation.GeolocationsImpl;
import com.azure.maps.geolocation.implementation.models.ErrorResponseException;
import com.azure.maps.geolocation.models.IpAddressToLocationResult;
import com.azure.maps.geolocation.implementation.models.JsonFormat;
import reactor.core.publisher.Mono;

/** Initializes a new instance of the asynchronous GeolocationClient type. 
* Creating an async client using a {@link com.azure.core.credential.AzureKeyCredential}:
* <!-- src_embed com.azure.maps.geolocation.async.builder.key.instantiation -->
* <pre>
* &#47;&#47; Authenticates using subscription key
* AzureKeyCredential keyCredential = new AzureKeyCredential&#40;System.getenv&#40;&quot;SUBSCRIPTION_KEY&quot;&#41;&#41;;
*
* &#47;&#47; Creates an async client
* GeolocationAsyncClient asyncClient = new GeolocationClientBuilder&#40;&#41;
*     .credential&#40;keyCredential&#41;
*     .buildAsyncClient&#40;&#41;;
* </pre>
* <!-- end com.azure.maps.geolocation.async.builder.key.instantiation -->
* Creating an async client using a {@link com.azure.core.credential.TokenCredential}:
* <!-- src_embed com.azure.maps.geolocation.async.builder.ad.instantiation -->
* <pre>
* &#47;&#47; Authenticates using Azure AD building a default credential
* &#47;&#47; This will look for AZURE_CLIENT_ID, AZURE_TENANT_ID, and AZURE_CLIENT_SECRET env variables
* DefaultAzureCredential tokenCredential = new DefaultAzureCredentialBuilder&#40;&#41;.build&#40;&#41;;
*
* &#47;&#47; Creates an async client
* GeolocationAsyncClient asyncClient = new GeolocationClientBuilder&#40;&#41;
*     .credential&#40;tokenCredential&#41;
*     .buildAsyncClient&#40;&#41;;
* </pre>
* <!-- end com.azure.maps.geolocation.async.builder.ad.instantiation -->
*/
@ServiceClient(builder = GeolocationClientBuilder.class, isAsync = true)
public final class GeolocationAsyncClient {
    private final GeolocationsImpl serviceClient;

    /**
     * Initializes an instance of GeolocationClient client.
     *
     * @param serviceClient the service client implementation.
     */
    GeolocationAsyncClient(GeolocationsImpl serviceClient) {
        this.serviceClient = serviceClient;
    }

    /**
     * Get Location
     * 
     * <!-- src_embed com.azure.maps.geolocation.async.get_ip_to_location -->
     * <pre>
     * asyncClient.getLocation&#40;&quot;131.107.0.89&quot;&#41;;
     * </pre>
     * <!-- end com.azure.maps.geolocation.async.get_ip_to_location -->
     * 
     * **Applies to**: S0 and S1 pricing tiers.
     *
     * <p>This service will return the ISO country code for the provided IP address. Developers can use this information
     * to block or alter certain content based on geographical locations where the application is being viewed from.
     *
     * @param ipAddress The IP address. Both IPv4 and IPv6 are allowed.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return this object is returned from a successful call to IP Address to country/region API.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<IpAddressToLocationResult> getLocation(String ipAddress) {
        Mono<Response<IpAddressToLocationResult>> result = this.getLocationWithResponse(ipAddress);
        return result.flatMap(response -> {
            return Mono.just(response.getValue());
        });
    }

    /**
     * Get Location
     *  
     * <!-- src_embed com.azure.maps.geolocation.async.get_ip_to_location -->
     * <pre>
     * asyncClient.getLocation&#40;&quot;131.107.0.89&quot;&#41;;
     * </pre>
     * <!-- end com.azure.maps.geolocation.async.get_ip_to_location -->
     * 
     * **Applies to**: S0 and S1 pricing tiers.
     *
     * <p>This service will return the ISO country code for the provided IP address. Developers can use this information
     * to block or alter certain content based on geographical locations where the application is being viewed from.
     *
     * @param ipAddress The IP address. Both IPv4 and IPv6 are allowed.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return this object is returned from a successful call to IP Address to country/region API.
     */
    @ServiceMethod(returns = ReturnType.SINGLE)
    public Mono<Response<IpAddressToLocationResult>> getLocationWithResponse(String ipAddress) {
        return this.getLocationWithResponse(ipAddress, null);
    }

    /**
     * Get Location
     * 
     * <!-- src_embed com.azure.maps.geolocation.async.get_ip_to_location -->
     * <pre>
     * asyncClient.getLocation&#40;&quot;131.107.0.89&quot;&#41;;
     * </pre>
     * <!-- end com.azure.maps.geolocation.async.get_ip_to_location -->
     * 
     * **Applies to**: S0 and S1 pricing tiers.
     *
     * <p>This service will return the ISO country code for the provided IP address. Developers can use this information
     * to block or alter certain content based on geographical locations where the application is being viewed from.
     *
     * @param context The context to associate with this operation.
     * @param ipAddress The IP address. Both IPv4 and IPv6 are allowed.
     * @throws IllegalArgumentException thrown if parameters fail the validation.
     * @throws HttpResponseException thrown if the request is rejected by server.
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent.
     * @return this object is returned from a successful call to IP Address to country/region API.
     */
    Mono<Response<IpAddressToLocationResult>> getLocationWithResponse(String ipAddress, Context context) {
        return this.serviceClient.getLocationWithResponseAsync(JsonFormat.JSON, ipAddress, context).onErrorMap(throwable -> {
            if (!(throwable instanceof ErrorResponseException)) {
                return throwable;
            }
            ErrorResponseException exception = (ErrorResponseException) throwable;
            return new HttpResponseException(exception.getMessage(), exception.getResponse());
        });
    }
}
