-- | Perhaps this module should be a separate package and published to hackage.
module Network.RabbitMqAdmin where

import Data.Aeson as Aeson
import Imports
import Servant
import Servant.Client
import Servant.Client.Generic

type RabbitMqBasicAuth = BasicAuth "RabbitMq Management" BasicAuthData

type VHost = Text

type QueueName = Text

data Page a = Page {forall a. Page a -> [a]
items :: [a], forall a. Page a -> Int
page :: Int, forall a. Page a -> Int
pageCount :: Int}
  deriving (Int -> Page a -> ShowS
[Page a] -> ShowS
Page a -> String
(Int -> Page a -> ShowS)
-> (Page a -> String) -> ([Page a] -> ShowS) -> Show (Page a)
forall a. Show a => Int -> Page a -> ShowS
forall a. Show a => [Page a] -> ShowS
forall a. Show a => Page a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Page a -> ShowS
showsPrec :: Int -> Page a -> ShowS
$cshow :: forall a. Show a => Page a -> String
show :: Page a -> String
$cshowList :: forall a. Show a => [Page a] -> ShowS
showList :: [Page a] -> ShowS
Show, Page a -> Page a -> Bool
(Page a -> Page a -> Bool)
-> (Page a -> Page a -> Bool) -> Eq (Page a)
forall a. Eq a => Page a -> Page a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Page a -> Page a -> Bool
== :: Page a -> Page a -> Bool
$c/= :: forall a. Eq a => Page a -> Page a -> Bool
/= :: Page a -> Page a -> Bool
Eq, (forall x. Page a -> Rep (Page a) x)
-> (forall x. Rep (Page a) x -> Page a) -> Generic (Page a)
forall x. Rep (Page a) x -> Page a
forall x. Page a -> Rep (Page a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Page a) x -> Page a
forall a x. Page a -> Rep (Page a) x
$cfrom :: forall a x. Page a -> Rep (Page a) x
from :: forall x. Page a -> Rep (Page a) x
$cto :: forall a x. Rep (Page a) x -> Page a
to :: forall x. Rep (Page a) x -> Page a
Generic)

instance (FromJSON a) => FromJSON (Page a) where
  parseJSON :: Value -> Parser (Page a)
parseJSON =
    Options -> Value -> Parser (Page a)
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON (Options -> Value -> Parser (Page a))
-> Options -> Value -> Parser (Page a)
forall a b. (a -> b) -> a -> b
$
      Options
defaultOptions
        { fieldLabelModifier = camelTo2 '_'
        }

instance (ToJSON a) => ToJSON (Page a) where
  toJSON :: Page a -> Value
toJSON =
    Options -> Page a -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON (Options -> Page a -> Value) -> Options -> Page a -> Value
forall a b. (a -> b) -> a -> b
$
      Options
defaultOptions
        { fieldLabelModifier = camelTo2 '_'
        }

-- | Upstream Docs:
-- https://rawcdn.githack.com/rabbitmq/rabbitmq-server/v3.12.0/deps/rabbitmq_management/priv/www/api/index.html
data AdminAPI route = AdminAPI
  { forall {k} (route :: k).
AdminAPI route
-> route
   :- ("api"
       :> ("queues"
           :> (Capture "vhost" Text
               :> (QueryParam' '[Required, Strict] "name" Text
                   :> (QueryParam' '[Required, Strict] "use_regex" Bool
                       :> (QueryParam' '[Required, Strict] "page_size" Int
                           :> (QueryParam' '[Required, Strict] "page" Int
                               :> Get '[JSON] (Page Queue))))))))
listQueuesByVHost ::
      route
        :- "api"
          :> "queues"
          :> Capture "vhost" VHost
          :> QueryParam' '[Required, Strict] "name" Text
          :> QueryParam' '[Required, Strict] "use_regex" Bool
          :> QueryParam' '[Required, Strict] "page_size" Int
          :> QueryParam' '[Required, Strict] "page" Int
          :> Get '[JSON] (Page Queue),
    forall {k} (route :: k).
AdminAPI route
-> route
   :- ("api"
       :> ("queues"
           :> (Capture "vhost" Text
               :> (Capture "queue" Text :> DeleteNoContent))))
deleteQueue ::
      route
        :- "api"
          :> "queues"
          :> Capture "vhost" VHost
          :> Capture "queue" QueueName
          :> DeleteNoContent,
    forall {k} (route :: k).
AdminAPI route
-> route
   :- ("api"
       :> ("vhosts"
           :> (Capture "vhost" Text
               :> ("connections" :> Get '[JSON] [Connection]))))
listConnectionsByVHost ::
      route
        :- "api"
          :> "vhosts"
          :> Capture "vhost" Text
          :> "connections"
          :> Get '[JSON] [Connection],
    forall {k} (route :: k).
AdminAPI route
-> route
   :- ("api"
       :> ("connections" :> (Capture "name" Text :> DeleteNoContent)))
deleteConnection ::
      route
        :- "api"
          :> "connections"
          :> Capture "name" Text
          :> DeleteNoContent
  }
  deriving ((forall x. AdminAPI route -> Rep (AdminAPI route) x)
-> (forall x. Rep (AdminAPI route) x -> AdminAPI route)
-> Generic (AdminAPI route)
forall x. Rep (AdminAPI route) x -> AdminAPI route
forall x. AdminAPI route -> Rep (AdminAPI route) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall k (route :: k) x. Rep (AdminAPI route) x -> AdminAPI route
forall k (route :: k) x. AdminAPI route -> Rep (AdminAPI route) x
$cfrom :: forall k (route :: k) x. AdminAPI route -> Rep (AdminAPI route) x
from :: forall x. AdminAPI route -> Rep (AdminAPI route) x
$cto :: forall k (route :: k) x. Rep (AdminAPI route) x -> AdminAPI route
to :: forall x. Rep (AdminAPI route) x -> AdminAPI route
Generic)

data AuthenticatedAPI route = AuthenticatedAPI
  { forall {k} (route :: k).
AuthenticatedAPI route
-> route :- (RabbitMqBasicAuth :> ToServant AdminAPI AsApi)
api ::
      route
        :- RabbitMqBasicAuth
          :> ToServant AdminAPI AsApi
  }
  deriving ((forall x.
 AuthenticatedAPI route -> Rep (AuthenticatedAPI route) x)
-> (forall x.
    Rep (AuthenticatedAPI route) x -> AuthenticatedAPI route)
-> Generic (AuthenticatedAPI route)
forall x. Rep (AuthenticatedAPI route) x -> AuthenticatedAPI route
forall x. AuthenticatedAPI route -> Rep (AuthenticatedAPI route) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall k (route :: k) x.
Rep (AuthenticatedAPI route) x -> AuthenticatedAPI route
forall k (route :: k) x.
AuthenticatedAPI route -> Rep (AuthenticatedAPI route) x
$cfrom :: forall k (route :: k) x.
AuthenticatedAPI route -> Rep (AuthenticatedAPI route) x
from :: forall x. AuthenticatedAPI route -> Rep (AuthenticatedAPI route) x
$cto :: forall k (route :: k) x.
Rep (AuthenticatedAPI route) x -> AuthenticatedAPI route
to :: forall x. Rep (AuthenticatedAPI route) x -> AuthenticatedAPI route
Generic)

jsonOptions :: Aeson.Options
jsonOptions :: Options
jsonOptions = Options
defaultOptions {fieldLabelModifier = camelTo2 '_'}

data Queue = Queue {Queue -> Text
name :: Text, Queue -> Text
vhost :: Text}
  deriving (Int -> Queue -> ShowS
[Queue] -> ShowS
Queue -> String
(Int -> Queue -> ShowS)
-> (Queue -> String) -> ([Queue] -> ShowS) -> Show Queue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Queue -> ShowS
showsPrec :: Int -> Queue -> ShowS
$cshow :: Queue -> String
show :: Queue -> String
$cshowList :: [Queue] -> ShowS
showList :: [Queue] -> ShowS
Show, Queue -> Queue -> Bool
(Queue -> Queue -> Bool) -> (Queue -> Queue -> Bool) -> Eq Queue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Queue -> Queue -> Bool
== :: Queue -> Queue -> Bool
$c/= :: Queue -> Queue -> Bool
/= :: Queue -> Queue -> Bool
Eq, (forall x. Queue -> Rep Queue x)
-> (forall x. Rep Queue x -> Queue) -> Generic Queue
forall x. Rep Queue x -> Queue
forall x. Queue -> Rep Queue x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Queue -> Rep Queue x
from :: forall x. Queue -> Rep Queue x
$cto :: forall x. Rep Queue x -> Queue
to :: forall x. Rep Queue x -> Queue
Generic)

instance FromJSON Queue

instance ToJSON Queue

data Connection = Connection
  { Connection -> Maybe Text
userProvidedName :: Maybe Text,
    Connection -> Text
name :: Text
  }
  deriving (Connection -> Connection -> Bool
(Connection -> Connection -> Bool)
-> (Connection -> Connection -> Bool) -> Eq Connection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Connection -> Connection -> Bool
== :: Connection -> Connection -> Bool
$c/= :: Connection -> Connection -> Bool
/= :: Connection -> Connection -> Bool
Eq, Int -> Connection -> ShowS
[Connection] -> ShowS
Connection -> String
(Int -> Connection -> ShowS)
-> (Connection -> String)
-> ([Connection] -> ShowS)
-> Show Connection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Connection -> ShowS
showsPrec :: Int -> Connection -> ShowS
$cshow :: Connection -> String
show :: Connection -> String
$cshowList :: [Connection] -> ShowS
showList :: [Connection] -> ShowS
Show, (forall x. Connection -> Rep Connection x)
-> (forall x. Rep Connection x -> Connection) -> Generic Connection
forall x. Rep Connection x -> Connection
forall x. Connection -> Rep Connection x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Connection -> Rep Connection x
from :: forall x. Connection -> Rep Connection x
$cto :: forall x. Rep Connection x -> Connection
to :: forall x. Rep Connection x -> Connection
Generic)

instance FromJSON Connection where
  parseJSON :: Value -> Parser Connection
parseJSON = Options -> Value -> Parser Connection
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
jsonOptions

instance ToJSON Connection where
  toJSON :: Connection -> Value
toJSON = Options -> Connection -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
jsonOptions

adminClient :: BasicAuthData -> AdminAPI (AsClientT ClientM)
adminClient :: BasicAuthData -> AdminAPI (AsClientT ClientM)
adminClient BasicAuthData
ba = ToServant AdminAPI (AsClientT ClientM)
-> AdminAPI (AsClientT ClientM)
forall {k} (routes :: k -> *) (mode :: k).
GenericServant routes mode =>
ToServant routes mode -> routes mode
fromServant (ToServant AdminAPI (AsClientT ClientM)
 -> AdminAPI (AsClientT ClientM))
-> ToServant AdminAPI (AsClientT ClientM)
-> AdminAPI (AsClientT ClientM)
forall a b. (a -> b) -> a -> b
$ AuthenticatedAPI (AsClientT ClientM)
clientWithAuth.api BasicAuthData
ba
  where
    clientWithAuth :: AuthenticatedAPI (AsClientT ClientM)
    clientWithAuth :: AuthenticatedAPI (AsClientT ClientM)
clientWithAuth = AuthenticatedAPI (AsClientT ClientM)
forall (routes :: * -> *) (m :: * -> *).
(HasClient m (ToServantApi routes),
 GenericServant routes (AsClientT m),
 Client m (ToServantApi routes) ~ ToServant routes (AsClientT m)) =>
routes (AsClientT m)
genericClient