{-# LANGUAGE DataKinds                   #-}
{-# LANGUAGE DeriveGeneric               #-}
{-# LANGUAGE FlexibleInstances           #-}
{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
{-# LANGUAGE LambdaCase                  #-}
{-# LANGUAGE NoImplicitPrelude           #-}
{-# LANGUAGE OverloadedStrings           #-}
{-# LANGUAGE RecordWildCards             #-}
{-# LANGUAGE TypeFamilies                #-}

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

-- Module      : Network.AWS.DataPipeline.QueryObjects
-- Copyright   : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
-- License     : This Source Code Form is subject to the terms of
--               the Mozilla Public License, v. 2.0.
--               A copy of the MPL can be found in the LICENSE file or
--               you can obtain it at http://mozilla.org/MPL/2.0/.
-- Maintainer  : Brendan Hay <brendan.g.hay@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)

-- | Queries a pipeline for the names of objects that match a specified set of
-- conditions. The objects returned by QueryObjects are paginated and then
-- filtered by the value you set for query. This means the action may return
-- an empty result set with a value set for marker. If HasMoreResults is set
-- to True, you should continue to call QueryObjects, passing in the returned
-- value for marker, until HasMoreResults returns False.
--
-- <http://docs.aws.amazon.com/datapipeline/latest/APIReference/API_QueryObjects.html>
module Network.AWS.DataPipeline.QueryObjects
    (
    -- * Request
      QueryObjects
    -- ** Request constructor
    , queryObjects
    -- ** Request lenses
    , qoLimit
    , qoMarker
    , qoPipelineId
    , qoQuery
    , qoSphere

    -- * Response
    , QueryObjectsResponse
    -- ** Response constructor
    , queryObjectsResponse
    -- ** Response lenses
    , qorHasMoreResults
    , qorIds
    , qorMarker
    ) where

import Network.AWS.Prelude
import Network.AWS.Request.JSON
import Network.AWS.DataPipeline.Types
import qualified GHC.Exts

data QueryObjects = QueryObjects
    { _qoLimit      :: Maybe Int
    , _qoMarker     :: Maybe Text
    , _qoPipelineId :: Text
    , _qoQuery      :: Maybe Query
    , _qoSphere     :: Text
    } deriving (Eq, Show)

-- | 'QueryObjects' constructor.
--
-- The fields accessible through corresponding lenses are:
--
-- * 'qoLimit' @::@ 'Maybe' 'Int'
--
-- * 'qoMarker' @::@ 'Maybe' 'Text'
--
-- * 'qoPipelineId' @::@ 'Text'
--
-- * 'qoQuery' @::@ 'Maybe' 'Query'
--
-- * 'qoSphere' @::@ 'Text'
--
queryObjects :: Text -- ^ 'qoPipelineId'
             -> Text -- ^ 'qoSphere'
             -> QueryObjects
queryObjects p1 p2 = QueryObjects
    { _qoPipelineId = p1
    , _qoSphere     = p2
    , _qoQuery      = Nothing
    , _qoMarker     = Nothing
    , _qoLimit      = Nothing
    }

-- | Specifies the maximum number of object names that QueryObjects will
-- return in a single call. The default value is 100.
qoLimit :: Lens' QueryObjects (Maybe Int)
qoLimit = lens _qoLimit (\s a -> s { _qoLimit = a })

-- | The starting point for the results to be returned. The first time you
-- call QueryObjects, this value should be empty. As long as the action
-- returns HasMoreResults as True, you can call QueryObjects again and pass
-- the marker value from the response to retrieve the next set of results.
qoMarker :: Lens' QueryObjects (Maybe Text)
qoMarker = lens _qoMarker (\s a -> s { _qoMarker = a })

-- | Identifier of the pipeline to be queried for object names.
qoPipelineId :: Lens' QueryObjects Text
qoPipelineId = lens _qoPipelineId (\s a -> s { _qoPipelineId = a })

-- | Query that defines the objects to be returned. The Query object can
-- contain a maximum of ten selectors. The conditions in the query are
-- limited to top-level String fields in the object. These filters can be
-- applied to components, instances, and attempts.
qoQuery :: Lens' QueryObjects (Maybe Query)
qoQuery = lens _qoQuery (\s a -> s { _qoQuery = a })

-- | Specifies whether the query applies to components or instances. Allowable
-- values: COMPONENT, INSTANCE, ATTEMPT.
qoSphere :: Lens' QueryObjects Text
qoSphere = lens _qoSphere (\s a -> s { _qoSphere = a })

data QueryObjectsResponse = QueryObjectsResponse
    { _qorHasMoreResults :: Maybe Bool
    , _qorIds            :: List "pipelineIds" Text
    , _qorMarker         :: Maybe Text
    } deriving (Eq, Ord, Show)

-- | 'QueryObjectsResponse' constructor.
--
-- The fields accessible through corresponding lenses are:
--
-- * 'qorHasMoreResults' @::@ 'Maybe' 'Bool'
--
-- * 'qorIds' @::@ ['Text']
--
-- * 'qorMarker' @::@ 'Maybe' 'Text'
--
queryObjectsResponse :: QueryObjectsResponse
queryObjectsResponse = QueryObjectsResponse
    { _qorIds            = mempty
    , _qorMarker         = Nothing
    , _qorHasMoreResults = Nothing
    }

-- | If True, there are more results that can be obtained by a subsequent call
-- to QueryObjects.
qorHasMoreResults :: Lens' QueryObjectsResponse (Maybe Bool)
qorHasMoreResults =
    lens _qorHasMoreResults (\s a -> s { _qorHasMoreResults = a })

-- | A list of identifiers that match the query selectors.
qorIds :: Lens' QueryObjectsResponse [Text]
qorIds = lens _qorIds (\s a -> s { _qorIds = a }) . _List

-- | The starting point for the results to be returned. As long as the action
-- returns HasMoreResults as True, you can call QueryObjects again and pass
-- the marker value from the response to retrieve the next set of results.
qorMarker :: Lens' QueryObjectsResponse (Maybe Text)
qorMarker = lens _qorMarker (\s a -> s { _qorMarker = a })

instance ToPath QueryObjects where
    toPath = const "/"

instance ToQuery QueryObjects where
    toQuery = const mempty

instance ToHeaders QueryObjects

instance ToJSON QueryObjects where
    toJSON QueryObjects{..} = object
        [ "pipelineId" .= _qoPipelineId
        , "query"      .= _qoQuery
        , "sphere"     .= _qoSphere
        , "marker"     .= _qoMarker
        , "limit"      .= _qoLimit
        ]

instance AWSRequest QueryObjects where
    type Sv QueryObjects = DataPipeline
    type Rs QueryObjects = QueryObjectsResponse

    request  = post "QueryObjects"
    response = jsonResponse

instance FromJSON QueryObjectsResponse where
    parseJSON = withObject "QueryObjectsResponse" $ \o -> QueryObjectsResponse
        <$> o .:? "hasMoreResults"
        <*> o .:  "ids"
        <*> o .:? "marker"

instance AWSPager QueryObjects where
    page rq rs
        | stop (rs ^. qorHasMoreResults) = Nothing
        | otherwise = Just $ rq
            & qoMarker .~ rs ^. qorMarker