/**
 * 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.vision.faceapi;

import com.microsoft.azure.cognitiveservices.vision.faceapi.models.FindSimilarOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.IdentifyOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.DetectWithUrlOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.DetectWithStreamOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.APIErrorException;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.DetectedFace;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.FaceAttributeType;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.FindSimilarMatchMode;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.GroupResult;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.IdentifyResult;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.SimilarFace;
import com.microsoft.azure.cognitiveservices.vision.faceapi.models.VerifyResult;
import java.util.List;
import java.util.UUID;
import rx.Observable;

/**
 * An instance of this class provides access to all the operations defined
 * in Faces.
 */
public interface Faces {
    /**
     * Given query face's faceId, find the similar-looking faces from a faceId array or a faceListId.
     *
     * @param faceId FaceId of the query face. User needs to call Face - Detect first to get a valid faceId. Note that this
     *   faceId is not persisted and will expire 24 hours after the detection call.
     * @param findSimilarOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws APIErrorException 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;SimilarFace&gt; object if successful.
     */
    
    List<SimilarFace> findSimilar(UUID faceId, FindSimilarOptionalParameter findSimilarOptionalParameter);

    /**
     * Given query face's faceId, find the similar-looking faces from a faceId array or a faceListId.
     *
     * @param faceId FaceId of the query face. User needs to call Face - Detect first to get a valid faceId. Note that this
     *   faceId is not persisted and will expire 24 hours after the detection call.
     * @param findSimilarOptionalParameter 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;SimilarFace&gt; object
     */
    
    Observable<List<SimilarFace>> findSimilarAsync(UUID faceId, FindSimilarOptionalParameter findSimilarOptionalParameter);

    /**
     * Given query face's faceId, find the similar-looking faces from a faceId array or a faceListId.
     *
     * @return the first stage of the findSimilar call
     */
    FacesFindSimilarDefinitionStages.WithFaceId findSimilar();

    /**
     * Grouping of findSimilar definition stages.
     */
    interface FacesFindSimilarDefinitionStages {
        /**
         * The stage of the definition to be specify faceId.
         */
        interface WithFaceId {
            /**
             * FaceId of the query face. User needs to call Face - Detect first to get a valid faceId. Note that this
             *   faceId is not persisted and will expire 24 hours after the detection call.
             *
             * @return next definition stage
             */
            FacesFindSimilarDefinitionStages.WithExecute withFaceId(UUID faceId);
        }

        /**
         * The stage of the definition which allows for any other optional settings to be specified.
         */
        interface WithAllOptions {
            /**
             * An existing user-specified unique candidate face list, created in Face List - Create a Face List. Face list
             *   contains a set of persistedFaceIds which are persisted and will never expire. Parameter faceListId and
             *   faceIds should not be provided at the same time.
             *
             * @return next definition stage
             */
            FacesFindSimilarDefinitionStages.WithExecute withFaceListId(String faceListId);

            /**
             * An array of candidate faceIds. All of them are created by Face - Detect and the faceIds will expire 24 hours
             *   after the detection call.
             *
             * @return next definition stage
             */
            FacesFindSimilarDefinitionStages.WithExecute withFaceIds(List<UUID> faceIds);

            /**
             * The number of top similar faces returned. The valid range is [1, 1000].
             *
             * @return next definition stage
             */
            FacesFindSimilarDefinitionStages.WithExecute withMaxNumOfCandidatesReturned(Integer maxNumOfCandidatesReturned);

            /**
             * Similar face searching mode. It can be "matchPerson" or "matchFace". Possible values include: 'matchPerson',
             *   'matchFace'.
             *
             * @return next definition stage
             */
            FacesFindSimilarDefinitionStages.WithExecute withMode(FindSimilarMatchMode mode);

        }

        /**
         * The last stage of the definition which will make the operation call.
        */
        interface WithExecute extends FacesFindSimilarDefinitionStages.WithAllOptions {
            /**
             * Execute the request.
             *
             * @return the List&lt;SimilarFace&gt; object if successful.
             */
            List<SimilarFace> execute();

            /**
             * Execute the request asynchronously.
             *
             * @return the observable to the List&lt;SimilarFace&gt; object
             */
            Observable<List<SimilarFace>> executeAsync();
        }
    }

    /**
     * The entirety of findSimilar definition.
     */
    interface FacesFindSimilarDefinition extends
        FacesFindSimilarDefinitionStages.WithFaceId,
        FacesFindSimilarDefinitionStages.WithExecute {
    }


    /**
     * Divide candidate faces into groups based on face similarity.
     *
     * @param faceIds Array of candidate faceId created by Face - Detect. The maximum is 1000 faces.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws APIErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the GroupResult object if successful.
     */
    GroupResult group(List<UUID> faceIds);

    /**
     * Divide candidate faces into groups based on face similarity.
     *
     * @param faceIds Array of candidate faceId created by Face - Detect. The maximum is 1000 faces.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the GroupResult object
     */
    Observable<GroupResult> groupAsync(List<UUID> faceIds);


    /**
     * Identify unknown faces from a person group.
     *
     * @param personGroupId PersonGroupId of the target person group, created by PersonGroups.Create.
     * @param faceIds Array of query faces faceIds, created by the Face - Detect. Each of the faces are identified independently.
     *   The valid number of faceIds is between [1, 10].
     * @param identifyOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws APIErrorException 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;IdentifyResult&gt; object if successful.
     */
    
    List<IdentifyResult> identify(String personGroupId, List<UUID> faceIds, IdentifyOptionalParameter identifyOptionalParameter);

    /**
     * Identify unknown faces from a person group.
     *
     * @param personGroupId PersonGroupId of the target person group, created by PersonGroups.Create.
     * @param faceIds Array of query faces faceIds, created by the Face - Detect. Each of the faces are identified independently.
     *   The valid number of faceIds is between [1, 10].
     * @param identifyOptionalParameter 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;IdentifyResult&gt; object
     */
    
    Observable<List<IdentifyResult>> identifyAsync(String personGroupId, List<UUID> faceIds, IdentifyOptionalParameter identifyOptionalParameter);

    /**
     * Identify unknown faces from a person group.
     *
     * @return the first stage of the identify call
     */
    FacesIdentifyDefinitionStages.WithPersonGroupId identify();

    /**
     * Grouping of identify definition stages.
     */
    interface FacesIdentifyDefinitionStages {
        /**
         * The stage of the definition to be specify personGroupId.
         */
        interface WithPersonGroupId {
            /**
             * PersonGroupId of the target person group, created by PersonGroups.Create.
             *
             * @return next definition stage
             */
            WithFaceIds withPersonGroupId(String personGroupId);
        }
        /**
         * The stage of the definition to be specify faceIds.
         */
        interface WithFaceIds {
            /**
             * Array of query faces faceIds, created by the Face - Detect. Each of the faces are identified independently.
             *   The valid number of faceIds is between [1, 10].
             *
             * @return next definition stage
             */
            FacesIdentifyDefinitionStages.WithExecute withFaceIds(List<UUID> faceIds);
        }

        /**
         * The stage of the definition which allows for any other optional settings to be specified.
         */
        interface WithAllOptions {
            /**
             * The range of maxNumOfCandidatesReturned is between 1 and 5 (default is 1).
             *
             * @return next definition stage
             */
            FacesIdentifyDefinitionStages.WithExecute withMaxNumOfCandidatesReturned(Integer maxNumOfCandidatesReturned);

            /**
             * Confidence threshold of identification, used to judge whether one face belong to one person. The range of
             *   confidenceThreshold is [0, 1] (default specified by algorithm).
             *
             * @return next definition stage
             */
            FacesIdentifyDefinitionStages.WithExecute withConfidenceThreshold(Double confidenceThreshold);

        }

        /**
         * The last stage of the definition which will make the operation call.
        */
        interface WithExecute extends FacesIdentifyDefinitionStages.WithAllOptions {
            /**
             * Execute the request.
             *
             * @return the List&lt;IdentifyResult&gt; object if successful.
             */
            List<IdentifyResult> execute();

            /**
             * Execute the request asynchronously.
             *
             * @return the observable to the List&lt;IdentifyResult&gt; object
             */
            Observable<List<IdentifyResult>> executeAsync();
        }
    }

    /**
     * The entirety of identify definition.
     */
    interface FacesIdentifyDefinition extends
        FacesIdentifyDefinitionStages.WithPersonGroupId,
        FacesIdentifyDefinitionStages.WithFaceIds,
        FacesIdentifyDefinitionStages.WithExecute {
    }


    /**
     * Verify whether two faces belong to a same person or whether one face belongs to a person.
     *
     * @param faceId1 FaceId of the first face, comes from Face - Detect.
     * @param faceId2 FaceId of the second face, comes from Face - Detect.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws APIErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the VerifyResult object if successful.
     */
    VerifyResult verifyFaceToFace(UUID faceId1, UUID faceId2);

    /**
     * Verify whether two faces belong to a same person or whether one face belongs to a person.
     *
     * @param faceId1 FaceId of the first face, comes from Face - Detect.
     * @param faceId2 FaceId of the second face, comes from Face - Detect.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the VerifyResult object
     */
    Observable<VerifyResult> verifyFaceToFaceAsync(UUID faceId1, UUID faceId2);


    /**
     * Detect human faces in an image and returns face locations, and optionally with faceIds, landmarks, and
     *   attributes.
     *
     * @param url Publicly reachable URL of an image.
     * @param detectWithUrlOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws APIErrorException 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;DetectedFace&gt; object if successful.
     */
    
    List<DetectedFace> detectWithUrl(String url, DetectWithUrlOptionalParameter detectWithUrlOptionalParameter);

    /**
     * Detect human faces in an image and returns face locations, and optionally with faceIds, landmarks, and
     *   attributes.
     *
     * @param url Publicly reachable URL of an image.
     * @param detectWithUrlOptionalParameter 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;DetectedFace&gt; object
     */
    
    Observable<List<DetectedFace>> detectWithUrlAsync(String url, DetectWithUrlOptionalParameter detectWithUrlOptionalParameter);

    /**
     * Detect human faces in an image and returns face locations, and optionally with faceIds, landmarks, and
     *   attributes.
     *
     * @return the first stage of the detectWithUrl call
     */
    FacesDetectWithUrlDefinitionStages.WithUrl detectWithUrl();

    /**
     * Grouping of detectWithUrl definition stages.
     */
    interface FacesDetectWithUrlDefinitionStages {
        /**
         * The stage of the definition to be specify url.
         */
        interface WithUrl {
            /**
             * Publicly reachable URL of an image.
             *
             * @return next definition stage
             */
            FacesDetectWithUrlDefinitionStages.WithExecute withUrl(String url);
        }

        /**
         * The stage of the definition which allows for any other optional settings to be specified.
         */
        interface WithAllOptions {
            /**
             * A value indicating whether the operation should return faceIds of detected faces.
             *
             * @return next definition stage
             */
            FacesDetectWithUrlDefinitionStages.WithExecute withReturnFaceId(Boolean returnFaceId);

            /**
             * A value indicating whether the operation should return landmarks of the detected faces.
             *
             * @return next definition stage
             */
            FacesDetectWithUrlDefinitionStages.WithExecute withReturnFaceLandmarks(Boolean returnFaceLandmarks);

            /**
             * Analyze and return the one or more specified face attributes in the comma-separated string like
             *   "returnFaceAttributes=age,gender". Supported face attributes include age, gender, headPose, smile,
             *   facialHair, glasses and emotion. Note that each face attribute analysis has additional computational and
             *   time cost.
             *
             * @return next definition stage
             */
            FacesDetectWithUrlDefinitionStages.WithExecute withReturnFaceAttributes(List<FaceAttributeType> returnFaceAttributes);

        }

        /**
         * The last stage of the definition which will make the operation call.
        */
        interface WithExecute extends FacesDetectWithUrlDefinitionStages.WithAllOptions {
            /**
             * Execute the request.
             *
             * @return the List&lt;DetectedFace&gt; object if successful.
             */
            List<DetectedFace> execute();

            /**
             * Execute the request asynchronously.
             *
             * @return the observable to the List&lt;DetectedFace&gt; object
             */
            Observable<List<DetectedFace>> executeAsync();
        }
    }

    /**
     * The entirety of detectWithUrl definition.
     */
    interface FacesDetectWithUrlDefinition extends
        FacesDetectWithUrlDefinitionStages.WithUrl,
        FacesDetectWithUrlDefinitionStages.WithExecute {
    }


    /**
     * Verify whether two faces belong to a same person. Compares a face Id with a Person Id.
     *
     * @param faceId FaceId the face, comes from Face - Detect.
     * @param personGroupId Using existing personGroupId and personId for fast loading a specified person. personGroupId is
      *  created in Person Groups.Create.
     * @param personId Specify a certain person in a person group. personId is created in Persons.Create.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws APIErrorException thrown if the request is rejected by server
     * @throws RuntimeException all other wrapped checked exceptions if the request fails to be sent
     * @return the VerifyResult object if successful.
     */
    VerifyResult verifyFaceToPerson(UUID faceId, String personGroupId, UUID personId);

    /**
     * Verify whether two faces belong to a same person. Compares a face Id with a Person Id.
     *
     * @param faceId FaceId the face, comes from Face - Detect.
     * @param personGroupId Using existing personGroupId and personId for fast loading a specified person. personGroupId is
      *  created in Person Groups.Create.
     * @param personId Specify a certain person in a person group. personId is created in Persons.Create.
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @return the observable to the VerifyResult object
     */
    Observable<VerifyResult> verifyFaceToPersonAsync(UUID faceId, String personGroupId, UUID personId);


    /**
     * Detect human faces in an image and returns face locations, and optionally with faceIds, landmarks, and
     *   attributes.
     *
     * @param image An image stream.
     * @param detectWithStreamOptionalParameter the object representing the optional parameters to be set before calling this API
     * @throws IllegalArgumentException thrown if parameters fail the validation
     * @throws APIErrorException 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;DetectedFace&gt; object if successful.
     */
    
    List<DetectedFace> detectWithStream(byte[] image, DetectWithStreamOptionalParameter detectWithStreamOptionalParameter);

    /**
     * Detect human faces in an image and returns face locations, and optionally with faceIds, landmarks, and
     *   attributes.
     *
     * @param image An image stream.
     * @param detectWithStreamOptionalParameter 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;DetectedFace&gt; object
     */
    
    Observable<List<DetectedFace>> detectWithStreamAsync(byte[] image, DetectWithStreamOptionalParameter detectWithStreamOptionalParameter);

    /**
     * Detect human faces in an image and returns face locations, and optionally with faceIds, landmarks, and
     *   attributes.
     *
     * @return the first stage of the detectWithStream call
     */
    FacesDetectWithStreamDefinitionStages.WithImage detectWithStream();

    /**
     * Grouping of detectWithStream definition stages.
     */
    interface FacesDetectWithStreamDefinitionStages {
        /**
         * The stage of the definition to be specify image.
         */
        interface WithImage {
            /**
             * An image stream.
             *
             * @return next definition stage
             */
            FacesDetectWithStreamDefinitionStages.WithExecute withImage(byte[] image);
        }

        /**
         * The stage of the definition which allows for any other optional settings to be specified.
         */
        interface WithAllOptions {
            /**
             * A value indicating whether the operation should return faceIds of detected faces.
             *
             * @return next definition stage
             */
            FacesDetectWithStreamDefinitionStages.WithExecute withReturnFaceId(Boolean returnFaceId);

            /**
             * A value indicating whether the operation should return landmarks of the detected faces.
             *
             * @return next definition stage
             */
            FacesDetectWithStreamDefinitionStages.WithExecute withReturnFaceLandmarks(Boolean returnFaceLandmarks);

            /**
             * Analyze and return the one or more specified face attributes in the comma-separated string like
             *   "returnFaceAttributes=age,gender". Supported face attributes include age, gender, headPose, smile,
             *   facialHair, glasses and emotion. Note that each face attribute analysis has additional computational and
             *   time cost.
             *
             * @return next definition stage
             */
            FacesDetectWithStreamDefinitionStages.WithExecute withReturnFaceAttributes(List<FaceAttributeType> returnFaceAttributes);

        }

        /**
         * The last stage of the definition which will make the operation call.
        */
        interface WithExecute extends FacesDetectWithStreamDefinitionStages.WithAllOptions {
            /**
             * Execute the request.
             *
             * @return the List&lt;DetectedFace&gt; object if successful.
             */
            List<DetectedFace> execute();

            /**
             * Execute the request asynchronously.
             *
             * @return the observable to the List&lt;DetectedFace&gt; object
             */
            Observable<List<DetectedFace>> executeAsync();
        }
    }

    /**
     * The entirety of detectWithStream definition.
     */
    interface FacesDetectWithStreamDefinition extends
        FacesDetectWithStreamDefinitionStages.WithImage,
        FacesDetectWithStreamDefinitionStages.WithExecute {
    }

}
