{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

-- |
-- Module      : Network.DO.Spaces.Actions.ListAllBuckets
-- Copyright   : (c) 2021 Rory Tyler Hayford
-- License     : BSD-3-Clause
-- Maintainer  : rory.hayford@protonmail.com
-- Stability   : experimental
-- Portability : GHC
--
module Network.DO.Spaces.Actions.ListAllBuckets
    ( ListAllBuckets(..)
    , ListAllBucketsResponse(..)
    ) where

import           Control.Monad.Reader    ( MonadReader(ask) )

import           Data.Coerce             ( coerce )
import           Data.Sequence           ( Seq )
import qualified Data.Sequence           as S

import           GHC.Generics            ( Generic )

import           Network.DO.Spaces.Types
                 ( Action(..)
                 , Bucket(Bucket)
                 , BucketInfo(..)
                 , MonadSpaces
                 , Owner(..)
                 , SpacesRequestBuilder(..)
                 )
import           Network.DO.Spaces.Utils
                 ( ownerP
                 , xmlDocCursor
                 , xmlElemError
                 , xmlUTCTime
                 )

import qualified Text.XML.Cursor         as X
import           Text.XML.Cursor         ( ($/), (&/), (&|) )

-- | List all of your 'Bucket's withing the 'Network.DO.Spaces.Region' you have configured
data ListAllBuckets = ListAllBuckets
    deriving ( Int -> ListAllBuckets -> ShowS
[ListAllBuckets] -> ShowS
ListAllBuckets -> String
(Int -> ListAllBuckets -> ShowS)
-> (ListAllBuckets -> String)
-> ([ListAllBuckets] -> ShowS)
-> Show ListAllBuckets
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ListAllBuckets] -> ShowS
$cshowList :: [ListAllBuckets] -> ShowS
show :: ListAllBuckets -> String
$cshow :: ListAllBuckets -> String
showsPrec :: Int -> ListAllBuckets -> ShowS
$cshowsPrec :: Int -> ListAllBuckets -> ShowS
Show, ListAllBuckets -> ListAllBuckets -> Bool
(ListAllBuckets -> ListAllBuckets -> Bool)
-> (ListAllBuckets -> ListAllBuckets -> Bool) -> Eq ListAllBuckets
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ListAllBuckets -> ListAllBuckets -> Bool
$c/= :: ListAllBuckets -> ListAllBuckets -> Bool
== :: ListAllBuckets -> ListAllBuckets -> Bool
$c== :: ListAllBuckets -> ListAllBuckets -> Bool
Eq, (forall x. ListAllBuckets -> Rep ListAllBuckets x)
-> (forall x. Rep ListAllBuckets x -> ListAllBuckets)
-> Generic ListAllBuckets
forall x. Rep ListAllBuckets x -> ListAllBuckets
forall x. ListAllBuckets -> Rep ListAllBuckets x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ListAllBuckets x -> ListAllBuckets
$cfrom :: forall x. ListAllBuckets -> Rep ListAllBuckets x
Generic )

data ListAllBucketsResponse =
    ListAllBucketsResponse { ListAllBucketsResponse -> Owner
owner :: Owner, ListAllBucketsResponse -> Seq BucketInfo
buckets :: Seq BucketInfo }
    deriving ( Int -> ListAllBucketsResponse -> ShowS
[ListAllBucketsResponse] -> ShowS
ListAllBucketsResponse -> String
(Int -> ListAllBucketsResponse -> ShowS)
-> (ListAllBucketsResponse -> String)
-> ([ListAllBucketsResponse] -> ShowS)
-> Show ListAllBucketsResponse
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ListAllBucketsResponse] -> ShowS
$cshowList :: [ListAllBucketsResponse] -> ShowS
show :: ListAllBucketsResponse -> String
$cshow :: ListAllBucketsResponse -> String
showsPrec :: Int -> ListAllBucketsResponse -> ShowS
$cshowsPrec :: Int -> ListAllBucketsResponse -> ShowS
Show, ListAllBucketsResponse -> ListAllBucketsResponse -> Bool
(ListAllBucketsResponse -> ListAllBucketsResponse -> Bool)
-> (ListAllBucketsResponse -> ListAllBucketsResponse -> Bool)
-> Eq ListAllBucketsResponse
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ListAllBucketsResponse -> ListAllBucketsResponse -> Bool
$c/= :: ListAllBucketsResponse -> ListAllBucketsResponse -> Bool
== :: ListAllBucketsResponse -> ListAllBucketsResponse -> Bool
$c== :: ListAllBucketsResponse -> ListAllBucketsResponse -> Bool
Eq, (forall x. ListAllBucketsResponse -> Rep ListAllBucketsResponse x)
-> (forall x.
    Rep ListAllBucketsResponse x -> ListAllBucketsResponse)
-> Generic ListAllBucketsResponse
forall x. Rep ListAllBucketsResponse x -> ListAllBucketsResponse
forall x. ListAllBucketsResponse -> Rep ListAllBucketsResponse x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ListAllBucketsResponse x -> ListAllBucketsResponse
$cfrom :: forall x. ListAllBucketsResponse -> Rep ListAllBucketsResponse x
Generic )

instance MonadSpaces m => Action m ListAllBuckets where
    type ConsumedResponse ListAllBuckets = ListAllBucketsResponse

    buildRequest :: ListAllBuckets -> m SpacesRequestBuilder
buildRequest ListAllBuckets
_ = do
        Spaces
spaces <- m Spaces
forall r (m :: * -> *). MonadReader r m => m r
ask
        SpacesRequestBuilder -> m SpacesRequestBuilder
forall (m :: * -> *) a. Monad m => a -> m a
return SpacesRequestBuilder :: Spaces
-> Maybe RequestBody
-> Maybe Method
-> [Header]
-> Maybe Bucket
-> Maybe Object
-> Maybe Query
-> Maybe Query
-> Maybe Region
-> SpacesRequestBuilder
SpacesRequestBuilder
               { $sel:body:SpacesRequestBuilder :: Maybe RequestBody
body           = Maybe RequestBody
forall a. Maybe a
Nothing
               , $sel:method:SpacesRequestBuilder :: Maybe Method
method         = Maybe Method
forall a. Maybe a
Nothing
               , $sel:object:SpacesRequestBuilder :: Maybe Object
object         = Maybe Object
forall a. Maybe a
Nothing
               , $sel:queryString:SpacesRequestBuilder :: Maybe Query
queryString    = Maybe Query
forall a. Maybe a
Nothing
               , $sel:subresources:SpacesRequestBuilder :: Maybe Query
subresources   = Maybe Query
forall a. Maybe a
Nothing
               , $sel:bucket:SpacesRequestBuilder :: Maybe Bucket
bucket         = Maybe Bucket
forall a. Maybe a
Nothing
               , $sel:headers:SpacesRequestBuilder :: [Header]
headers        = [Header]
forall a. Monoid a => a
mempty
               , $sel:overrideRegion:SpacesRequestBuilder :: Maybe Region
overrideRegion = Maybe Region
forall a. Maybe a
Nothing
               , Spaces
$sel:spaces:SpacesRequestBuilder :: Spaces
spaces :: Spaces
..
               }

    consumeResponse :: RawResponse m -> m (ConsumedResponse ListAllBuckets)
consumeResponse RawResponse m
raw = do
        Cursor
cursor <- RawResponse m -> m Cursor
forall (m :: * -> *).
(MonadIO m, MonadThrow m) =>
RawResponse m -> m Cursor
xmlDocCursor RawResponse m
raw
        Owner
owner <- ClientException -> [m Owner] -> m Owner
forall e (f :: * -> *) a.
(Exception e, MonadThrow f) =>
e -> [f a] -> f a
X.forceM (Text -> ClientException
xmlElemError Text
"Owner")
            ([m Owner] -> m Owner) -> [m Owner] -> m Owner
forall a b. (a -> b) -> a -> b
$ Cursor
cursor Cursor -> (Cursor -> [m Owner]) -> [m Owner]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
X.laxElement Text
"Owner" Axis -> (Cursor -> m Owner) -> Cursor -> [m Owner]
forall node a b.
(Cursor node -> [a]) -> (a -> b) -> Cursor node -> [b]
&| Cursor -> m Owner
forall (m :: * -> *). MonadThrow m => Cursor -> m Owner
ownerP
        [BucketInfo]
bs <- ClientException -> [[BucketInfo]] -> m [BucketInfo]
forall e (f :: * -> *) a.
(Exception e, MonadThrow f) =>
e -> [a] -> f a
X.force (Text -> ClientException
xmlElemError Text
"Buckets")
            ([[BucketInfo]] -> m [BucketInfo])
-> [[BucketInfo]] -> m [BucketInfo]
forall a b. (a -> b) -> a -> b
$ Cursor
cursor Cursor -> (Cursor -> [[BucketInfo]]) -> [[BucketInfo]]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
X.laxElement Text
"Buckets" Axis -> (Cursor -> [BucketInfo]) -> Cursor -> [[BucketInfo]]
forall node a b.
(Cursor node -> [a]) -> (a -> b) -> Cursor node -> [b]
&| Cursor -> [BucketInfo]
bucketsP
        ListAllBucketsResponse -> m ListAllBucketsResponse
forall (m :: * -> *) a. Monad m => a -> m a
return ListAllBucketsResponse :: Owner -> Seq BucketInfo -> ListAllBucketsResponse
ListAllBucketsResponse { buckets :: Seq BucketInfo
buckets = [BucketInfo] -> Seq BucketInfo
forall a. [a] -> Seq a
S.fromList [BucketInfo]
bs, Owner
owner :: Owner
owner :: Owner
.. }
      where
        bucketsP :: Cursor -> [BucketInfo]
bucketsP Cursor
c = ClientException -> [[BucketInfo]] -> [BucketInfo]
forall e (f :: * -> *) a.
(Exception e, MonadThrow f) =>
e -> [f a] -> f a
X.forceM (Text -> ClientException
xmlElemError Text
"Bucket") ([[BucketInfo]] -> [BucketInfo])
-> ([[BucketInfo]] -> [[BucketInfo]])
-> [[BucketInfo]]
-> [BucketInfo]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[BucketInfo]] -> [[BucketInfo]]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence
            ([[BucketInfo]] -> [BucketInfo]) -> [[BucketInfo]] -> [BucketInfo]
forall a b. (a -> b) -> a -> b
$ Cursor
c Cursor -> (Cursor -> [[BucketInfo]]) -> [[BucketInfo]]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
X.laxElement Text
"Bucket" Axis -> (Cursor -> [BucketInfo]) -> Cursor -> [[BucketInfo]]
forall node a b.
(Cursor node -> [a]) -> (a -> b) -> Cursor node -> [b]
&| Cursor -> [BucketInfo]
forall (m :: * -> *). MonadThrow m => Cursor -> m BucketInfo
bucketInfoP

        bucketInfoP :: Cursor -> m BucketInfo
bucketInfoP Cursor
c = do
            Bucket
name <- ClientException -> [Bucket] -> m Bucket
forall e (f :: * -> *) a.
(Exception e, MonadThrow f) =>
e -> [a] -> f a
X.force (Text -> ClientException
xmlElemError Text
"Name")
                ([Bucket] -> m Bucket) -> [Bucket] -> m Bucket
forall a b. (a -> b) -> a -> b
$ Cursor
c Cursor -> (Cursor -> [Bucket]) -> [Bucket]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
X.laxElement Text
"Name" Axis -> (Cursor -> [Bucket]) -> Cursor -> [Bucket]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
X.content (Cursor -> [Text]) -> (Text -> Bucket) -> Cursor -> [Bucket]
forall node a b.
(Cursor node -> [a]) -> (a -> b) -> Cursor node -> [b]
&| Text -> Bucket
coerce
            UTCTime
creationDate <- ClientException -> [m UTCTime] -> m UTCTime
forall e (f :: * -> *) a.
(Exception e, MonadThrow f) =>
e -> [f a] -> f a
X.forceM (Text -> ClientException
xmlElemError Text
"Creation date")
                ([m UTCTime] -> m UTCTime) -> [m UTCTime] -> m UTCTime
forall a b. (a -> b) -> a -> b
$ Cursor
c Cursor -> (Cursor -> [m UTCTime]) -> [m UTCTime]
forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
X.laxElement Text
"CreationDate" Axis -> (Cursor -> [m UTCTime]) -> Cursor -> [m UTCTime]
forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
X.content (Cursor -> [Text]) -> (Text -> m UTCTime) -> Cursor -> [m UTCTime]
forall node a b.
(Cursor node -> [a]) -> (a -> b) -> Cursor node -> [b]
&| Text -> m UTCTime
forall (m :: * -> *). MonadThrow m => Text -> m UTCTime
xmlUTCTime
            BucketInfo -> m BucketInfo
forall (m :: * -> *) a. Monad m => a -> m a
return BucketInfo :: Bucket -> UTCTime -> BucketInfo
BucketInfo { UTCTime
Bucket
$sel:creationDate:BucketInfo :: UTCTime
$sel:name:BucketInfo :: Bucket
creationDate :: UTCTime
name :: Bucket
.. }