{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric      #-}
{-# LANGUAGE OverloadedStrings  #-}
{-# LANGUAGE RecordWildCards    #-}
{-# LANGUAGE TypeFamilies       #-}

{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-unused-binds   #-}
{-# OPTIONS_GHC -fno-warn-unused-matches #-}

-- Derived from AWS service descriptions, licensed under Apache 2.0.

-- |
-- Module      : Network.AWS.Rekognition.SearchFacesByImage
-- Copyright   : (c) 2013-2016 Brendan Hay
-- License     : Mozilla Public License, v. 2.0.
-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
-- Stability   : auto-generated
-- Portability : non-portable (GHC extensions)
--
-- For a given input image, first detects the largest face in the image, and then searches the specified collection for matching faces. The operation compares the features of the input face with faces in the specified collection.
--
--
-- The response returns an array of faces that match, ordered by similarity score with the highest similarity first. More specifically, it is an array of metadata for each face match found. Along with the metadata, the response also includes a @similarity@ indicating how similar the face is to the input face. In the response, the API also returns the bounding box (and a confidence level that the bounding box contains a face) of the face that Rekognition used for the input image.
--
-- For an example, see 'example3' .
--
-- This operation requires permissions to perform the @rekognition:SearchFacesByImage@ action.
--
module Network.AWS.Rekognition.SearchFacesByImage
    (
    -- * Creating a Request
      searchFacesByImage
    , SearchFacesByImage
    -- * Request Lenses
    , sfbiFaceMatchThreshold
    , sfbiMaxFaces
    , sfbiCollectionId
    , sfbiImage

    -- * Destructuring the Response
    , searchFacesByImageResponse
    , SearchFacesByImageResponse
    -- * Response Lenses
    , sfbirsFaceMatches
    , sfbirsSearchedFaceBoundingBox
    , sfbirsSearchedFaceConfidence
    , sfbirsResponseStatus
    ) where

import           Network.AWS.Lens
import           Network.AWS.Prelude
import           Network.AWS.Rekognition.Types
import           Network.AWS.Rekognition.Types.Product
import           Network.AWS.Request
import           Network.AWS.Response

-- | /See:/ 'searchFacesByImage' smart constructor.
data SearchFacesByImage = SearchFacesByImage'
    { _sfbiFaceMatchThreshold :: !(Maybe Double)
    , _sfbiMaxFaces           :: !(Maybe Nat)
    , _sfbiCollectionId       :: !Text
    , _sfbiImage              :: !Image
    } deriving (Eq,Read,Show,Data,Typeable,Generic)

-- | Creates a value of 'SearchFacesByImage' with the minimum fields required to make a request.
--
-- Use one of the following lenses to modify other fields as desired:
--
-- * 'sfbiFaceMatchThreshold' - (Optional) Specifies the minimum confidence in the face match to return. For example, don't return any matches where confidence in matches is less than 70%.
--
-- * 'sfbiMaxFaces' - Maximum number of faces to return. The operation returns the maximum number of faces with the highest confidence in the match.
--
-- * 'sfbiCollectionId' - ID of the collection to search.
--
-- * 'sfbiImage' - Undocumented member.
searchFacesByImage
    :: Text -- ^ 'sfbiCollectionId'
    -> Image -- ^ 'sfbiImage'
    -> SearchFacesByImage
searchFacesByImage pCollectionId_ pImage_ =
    SearchFacesByImage'
    { _sfbiFaceMatchThreshold = Nothing
    , _sfbiMaxFaces = Nothing
    , _sfbiCollectionId = pCollectionId_
    , _sfbiImage = pImage_
    }

-- | (Optional) Specifies the minimum confidence in the face match to return. For example, don't return any matches where confidence in matches is less than 70%.
sfbiFaceMatchThreshold :: Lens' SearchFacesByImage (Maybe Double)
sfbiFaceMatchThreshold = lens _sfbiFaceMatchThreshold (\ s a -> s{_sfbiFaceMatchThreshold = a});

-- | Maximum number of faces to return. The operation returns the maximum number of faces with the highest confidence in the match.
sfbiMaxFaces :: Lens' SearchFacesByImage (Maybe Natural)
sfbiMaxFaces = lens _sfbiMaxFaces (\ s a -> s{_sfbiMaxFaces = a}) . mapping _Nat;

-- | ID of the collection to search.
sfbiCollectionId :: Lens' SearchFacesByImage Text
sfbiCollectionId = lens _sfbiCollectionId (\ s a -> s{_sfbiCollectionId = a});

-- | Undocumented member.
sfbiImage :: Lens' SearchFacesByImage Image
sfbiImage = lens _sfbiImage (\ s a -> s{_sfbiImage = a});

instance AWSRequest SearchFacesByImage where
        type Rs SearchFacesByImage =
             SearchFacesByImageResponse
        request = postJSON rekognition
        response
          = receiveJSON
              (\ s h x ->
                 SearchFacesByImageResponse' <$>
                   (x .?> "FaceMatches" .!@ mempty) <*>
                     (x .?> "SearchedFaceBoundingBox")
                     <*> (x .?> "SearchedFaceConfidence")
                     <*> (pure (fromEnum s)))

instance Hashable SearchFacesByImage

instance NFData SearchFacesByImage

instance ToHeaders SearchFacesByImage where
        toHeaders
          = const
              (mconcat
                 ["X-Amz-Target" =#
                    ("RekognitionService.SearchFacesByImage" ::
                       ByteString),
                  "Content-Type" =#
                    ("application/x-amz-json-1.1" :: ByteString)])

instance ToJSON SearchFacesByImage where
        toJSON SearchFacesByImage'{..}
          = object
              (catMaybes
                 [("FaceMatchThreshold" .=) <$>
                    _sfbiFaceMatchThreshold,
                  ("MaxFaces" .=) <$> _sfbiMaxFaces,
                  Just ("CollectionId" .= _sfbiCollectionId),
                  Just ("Image" .= _sfbiImage)])

instance ToPath SearchFacesByImage where
        toPath = const "/"

instance ToQuery SearchFacesByImage where
        toQuery = const mempty

-- | /See:/ 'searchFacesByImageResponse' smart constructor.
data SearchFacesByImageResponse = SearchFacesByImageResponse'
    { _sfbirsFaceMatches             :: !(Maybe [FaceMatch])
    , _sfbirsSearchedFaceBoundingBox :: !(Maybe BoundingBox)
    , _sfbirsSearchedFaceConfidence  :: !(Maybe Double)
    , _sfbirsResponseStatus          :: !Int
    } deriving (Eq,Read,Show,Data,Typeable,Generic)

-- | Creates a value of 'SearchFacesByImageResponse' with the minimum fields required to make a request.
--
-- Use one of the following lenses to modify other fields as desired:
--
-- * 'sfbirsFaceMatches' - An array of faces that match the input face, along with the confidence in the match.
--
-- * 'sfbirsSearchedFaceBoundingBox' - The bounding box around the face in the input image that Rekognition used for the search.
--
-- * 'sfbirsSearchedFaceConfidence' - The level of confidence that the @searchedFaceBoundingBox@ , contains a face.
--
-- * 'sfbirsResponseStatus' - -- | The response status code.
searchFacesByImageResponse
    :: Int -- ^ 'sfbirsResponseStatus'
    -> SearchFacesByImageResponse
searchFacesByImageResponse pResponseStatus_ =
    SearchFacesByImageResponse'
    { _sfbirsFaceMatches = Nothing
    , _sfbirsSearchedFaceBoundingBox = Nothing
    , _sfbirsSearchedFaceConfidence = Nothing
    , _sfbirsResponseStatus = pResponseStatus_
    }

-- | An array of faces that match the input face, along with the confidence in the match.
sfbirsFaceMatches :: Lens' SearchFacesByImageResponse [FaceMatch]
sfbirsFaceMatches = lens _sfbirsFaceMatches (\ s a -> s{_sfbirsFaceMatches = a}) . _Default . _Coerce;

-- | The bounding box around the face in the input image that Rekognition used for the search.
sfbirsSearchedFaceBoundingBox :: Lens' SearchFacesByImageResponse (Maybe BoundingBox)
sfbirsSearchedFaceBoundingBox = lens _sfbirsSearchedFaceBoundingBox (\ s a -> s{_sfbirsSearchedFaceBoundingBox = a});

-- | The level of confidence that the @searchedFaceBoundingBox@ , contains a face.
sfbirsSearchedFaceConfidence :: Lens' SearchFacesByImageResponse (Maybe Double)
sfbirsSearchedFaceConfidence = lens _sfbirsSearchedFaceConfidence (\ s a -> s{_sfbirsSearchedFaceConfidence = a});

-- | -- | The response status code.
sfbirsResponseStatus :: Lens' SearchFacesByImageResponse Int
sfbirsResponseStatus = lens _sfbirsResponseStatus (\ s a -> s{_sfbirsResponseStatus = a});

instance NFData SearchFacesByImageResponse