    module Aws.S3.Commands.HeadObject
    where

    import           Aws.Core
    import           Aws.S3.Core
    import           Control.Applicative
    import           Data.ByteString.Char8 ({- IsString -})
    import qualified Data.ByteString.Char8 as B8
    import           Data.Maybe
    import qualified Data.Text             as T
    import qualified Data.Text.Encoding    as T
    import           Prelude
    import qualified Network.HTTP.Conduit  as HTTP
    import qualified Network.HTTP.Types    as HTTP

    data HeadObject
        = HeadObject {
            HeadObject -> Bucket
    hoBucket :: Bucket
          , HeadObject -> Bucket
    hoObjectName :: Object
          , HeadObject -> Maybe Bucket
    hoVersionId :: Maybe T.Text
          , HeadObject -> Maybe Bucket
    hoIfMatch :: Maybe T.Text
          -- ^ Return the object only if its entity tag (ETag, which is an md5sum of the content) is the same as the one specified; otherwise, catch a 'StatusCodeException' with a status of 412 precondition failed.
          , HeadObject -> Maybe Bucket
    hoIfNoneMatch :: Maybe T.Text
          -- ^ Return the object only if its entity tag (ETag, which is an md5sum of the content) is different from the one specified; otherwise, catch a 'StatusCodeException' with a status of 304 not modified.
          }
      deriving (Int -> HeadObject -> ShowS
    [HeadObject] -> ShowS
    HeadObject -> String
    (Int -> HeadObject -> ShowS)
    -> (HeadObject -> String)
    -> ([HeadObject] -> ShowS)
    -> Show HeadObject
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> HeadObject -> ShowS
    showsPrec :: Int -> HeadObject -> ShowS
    $cshow :: HeadObject -> String
    show :: HeadObject -> String
    $cshowList :: [HeadObject] -> ShowS
    showList :: [HeadObject] -> ShowS
    Show)

    headObject :: Bucket -> T.Text -> HeadObject
    headObject :: Bucket -> Bucket -> HeadObject
    headObject Bucket
    b Bucket
    o = Bucket
    -> Bucket
    -> Maybe Bucket
    -> Maybe Bucket
    -> Maybe Bucket
    -> HeadObject
    HeadObject Bucket
    b Bucket
    o Maybe Bucket
    forall a. Maybe a
    Nothing Maybe Bucket
    forall a. Maybe a
    Nothing Maybe Bucket
    forall a. Maybe a
    Nothing

    data HeadObjectResponse
        = HeadObjectResponse {
            HeadObjectResponse -> Maybe ObjectMetadata
    horMetadata :: Maybe ObjectMetadata
          } deriving (Int -> HeadObjectResponse -> ShowS
    [HeadObjectResponse] -> ShowS
    HeadObjectResponse -> String
    (Int -> HeadObjectResponse -> ShowS)
    -> (HeadObjectResponse -> String)
    -> ([HeadObjectResponse] -> ShowS)
    -> Show HeadObjectResponse
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> HeadObjectResponse -> ShowS
    showsPrec :: Int -> HeadObjectResponse -> ShowS
    $cshow :: HeadObjectResponse -> String
    show :: HeadObjectResponse -> String
    $cshowList :: [HeadObjectResponse] -> ShowS
    showList :: [HeadObjectResponse] -> ShowS
    Show)

    data HeadObjectMemoryResponse
        = HeadObjectMemoryResponse (Maybe ObjectMetadata)
        deriving (Int -> HeadObjectMemoryResponse -> ShowS
    [HeadObjectMemoryResponse] -> ShowS
    HeadObjectMemoryResponse -> String
    (Int -> HeadObjectMemoryResponse -> ShowS)
    -> (HeadObjectMemoryResponse -> String)
    -> ([HeadObjectMemoryResponse] -> ShowS)
    -> Show HeadObjectMemoryResponse
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> HeadObjectMemoryResponse -> ShowS
    showsPrec :: Int -> HeadObjectMemoryResponse -> ShowS
    $cshow :: HeadObjectMemoryResponse -> String
    show :: HeadObjectMemoryResponse -> String
    $cshowList :: [HeadObjectMemoryResponse] -> ShowS
    showList :: [HeadObjectMemoryResponse] -> ShowS
    Show)

    -- | ServiceConfiguration: 'S3Configuration'
    instance SignQuery HeadObject where
        type ServiceConfiguration HeadObject = S3Configuration
        signQuery :: forall queryType.
    HeadObject
    -> ServiceConfiguration HeadObject queryType
    -> SignatureData
    -> SignedQuery
    signQuery HeadObject {Maybe Bucket
    Bucket
    hoBucket :: HeadObject -> Bucket
    hoObjectName :: HeadObject -> Bucket
    hoVersionId :: HeadObject -> Maybe Bucket
    hoIfMatch :: HeadObject -> Maybe Bucket
    hoIfNoneMatch :: HeadObject -> Maybe Bucket
    hoBucket :: Bucket
    hoObjectName :: Bucket
    hoVersionId :: Maybe Bucket
    hoIfMatch :: Maybe Bucket
    hoIfNoneMatch :: Maybe Bucket
    ..} = S3Query
    -> S3Configuration queryType -> SignatureData -> SignedQuery
    forall qt.
    S3Query -> S3Configuration qt -> SignatureData -> SignedQuery
    s3SignQuery S3Query {
                                       s3QMethod :: Method
    s3QMethod = Method
    Head
                                     , s3QBucket :: Maybe ByteString
    s3QBucket = ByteString -> Maybe ByteString
    forall a. a -> Maybe a
    Just (ByteString -> Maybe ByteString) -> ByteString -> Maybe ByteString
    forall a b. (a -> b) -> a -> b
    $ Bucket -> ByteString
    T.encodeUtf8 Bucket
    hoBucket
                                     , s3QObject :: Maybe ByteString
    s3QObject = ByteString -> Maybe ByteString
    forall a. a -> Maybe a
    Just (ByteString -> Maybe ByteString) -> ByteString -> Maybe ByteString
    forall a b. (a -> b) -> a -> b
    $ Bucket -> ByteString
    T.encodeUtf8 Bucket
    hoObjectName
                                     , s3QSubresources :: Query
    s3QSubresources = [Maybe (ByteString, Bucket)] -> Query
    forall a. QueryLike a => a -> Query
    HTTP.toQuery [
                                                           (ByteString
    "versionId" :: B8.ByteString,) (Bucket -> (ByteString, Bucket))
    -> Maybe Bucket -> Maybe (ByteString, Bucket)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Maybe Bucket
    hoVersionId
                                                         ]
                                     , s3QQuery :: Query
    s3QQuery = []
                                     , s3QContentType :: Maybe ByteString
    s3QContentType = Maybe ByteString
    forall a. Maybe a
    Nothing
                                     , s3QContentMd5 :: Maybe (Digest MD5)
    s3QContentMd5 = Maybe (Digest MD5)
    forall a. Maybe a
    Nothing
                                     , s3QAmzHeaders :: RequestHeaders
    s3QAmzHeaders = []
                                     , s3QOtherHeaders :: RequestHeaders
    s3QOtherHeaders = [Maybe Header] -> RequestHeaders
    forall a. [Maybe a] -> [a]
    catMaybes [
                                                           (HeaderName
    "if-match",) (ByteString -> Header)
    -> (Bucket -> ByteString) -> Bucket -> Header
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Bucket -> ByteString
    T.encodeUtf8 (Bucket -> Header) -> Maybe Bucket -> Maybe Header
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Maybe Bucket
    hoIfMatch
                                                         , (HeaderName
    "if-none-match",) (ByteString -> Header)
    -> (Bucket -> ByteString) -> Bucket -> Header
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Bucket -> ByteString
    T.encodeUtf8 (Bucket -> Header) -> Maybe Bucket -> Maybe Header
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Maybe Bucket
    hoIfNoneMatch
                                                         ]
                                     , s3QRequestBody :: Maybe RequestBody
    s3QRequestBody = Maybe RequestBody
    forall a. Maybe a
    Nothing
                                     }

    instance ResponseConsumer HeadObject HeadObjectResponse where
        type ResponseMetadata HeadObjectResponse = S3Metadata
        responseConsumer :: Request
    -> HeadObject
    -> IORef (ResponseMetadata HeadObjectResponse)
    -> HTTPResponseConsumer HeadObjectResponse
    responseConsumer Request
    httpReq HeadObject{} IORef (ResponseMetadata HeadObjectResponse)
    _ Response (ConduitM () ByteString (ResourceT IO) ())
    resp
            | Status
    status Status -> Status -> Bool
    forall a. Eq a => a -> a -> Bool
    == Status
    HTTP.status200 = Maybe ObjectMetadata -> HeadObjectResponse
    HeadObjectResponse (Maybe ObjectMetadata -> HeadObjectResponse)
    -> (ObjectMetadata -> Maybe ObjectMetadata)
    -> ObjectMetadata
    -> HeadObjectResponse
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ObjectMetadata -> Maybe ObjectMetadata
    forall a. a -> Maybe a
    Just (ObjectMetadata -> HeadObjectResponse)
    -> ResourceT IO ObjectMetadata -> ResourceT IO HeadObjectResponse
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> RequestHeaders -> ResourceT IO ObjectMetadata
    forall (m :: * -> *).
    MonadThrow m =>
    RequestHeaders -> m ObjectMetadata
    parseObjectMetadata RequestHeaders
    headers
            | Status
    status Status -> Status -> Bool
    forall a. Eq a => a -> a -> Bool
    == Status
    HTTP.status404 = HeadObjectResponse -> ResourceT IO HeadObjectResponse
    forall a. a -> ResourceT IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (HeadObjectResponse -> ResourceT IO HeadObjectResponse)
    -> HeadObjectResponse -> ResourceT IO HeadObjectResponse
    forall a b. (a -> b) -> a -> b
    $ Maybe ObjectMetadata -> HeadObjectResponse
    HeadObjectResponse Maybe ObjectMetadata
    forall a. Maybe a
    Nothing
            | Bool
    otherwise = Request -> HTTPResponseConsumer HeadObjectResponse
    forall (m :: * -> *) a.
    MonadThrow m =>
    Request -> Response (ConduitM () ByteString m ()) -> m a
    throwStatusCodeException Request
    httpReq Response (ConduitM () ByteString (ResourceT IO) ())
    resp
          where
            status :: Status
    status  = Response (ConduitM () ByteString (ResourceT IO) ()) -> Status
    forall body. Response body -> Status
    HTTP.responseStatus    Response (ConduitM () ByteString (ResourceT IO) ())
    resp
            headers :: RequestHeaders
    headers = Response (ConduitM () ByteString (ResourceT IO) ())
    -> RequestHeaders
    forall body. Response body -> RequestHeaders
    HTTP.responseHeaders   Response (ConduitM () ByteString (ResourceT IO) ())
    resp

    instance Transaction HeadObject HeadObjectResponse

    instance AsMemoryResponse HeadObjectResponse where
        type MemoryResponse HeadObjectResponse = HeadObjectMemoryResponse
        loadToMemory :: HeadObjectResponse
    -> ResourceT IO (MemoryResponse HeadObjectResponse)
    loadToMemory (HeadObjectResponse Maybe ObjectMetadata
    om) = HeadObjectMemoryResponse -> ResourceT IO HeadObjectMemoryResponse
    forall a. a -> ResourceT IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe ObjectMetadata -> HeadObjectMemoryResponse
    HeadObjectMemoryResponse Maybe ObjectMetadata
    om)