module Hydra.API.APIServerLog where

import Hydra.Prelude

import Data.Aeson qualified as Aeson
import Hydra.Network (PortNumber)

data APIServerLog
  = APIServerStarted {APIServerLog -> PortNumber
listeningPort :: PortNumber}
  | NewAPIConnection
  | APIOutputSent {APIServerLog -> Value
sentOutput :: Aeson.Value}
  | APIInputReceived {APIServerLog -> Value
receivedInput :: Aeson.Value}
  | APIInvalidInput {APIServerLog -> String
reason :: String, APIServerLog -> Text
inputReceived :: Text}
  | APIConnectionError {reason :: String}
  | APIHTTPRequestReceived
      { APIServerLog -> Method
method :: Method
      , APIServerLog -> PathInfo
path :: PathInfo
      }
  deriving stock (APIServerLog -> APIServerLog -> Bool
(APIServerLog -> APIServerLog -> Bool)
-> (APIServerLog -> APIServerLog -> Bool) -> Eq APIServerLog
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: APIServerLog -> APIServerLog -> Bool
== :: APIServerLog -> APIServerLog -> Bool
$c/= :: APIServerLog -> APIServerLog -> Bool
/= :: APIServerLog -> APIServerLog -> Bool
Eq, Int -> APIServerLog -> ShowS
[APIServerLog] -> ShowS
APIServerLog -> String
(Int -> APIServerLog -> ShowS)
-> (APIServerLog -> String)
-> ([APIServerLog] -> ShowS)
-> Show APIServerLog
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> APIServerLog -> ShowS
showsPrec :: Int -> APIServerLog -> ShowS
$cshow :: APIServerLog -> String
show :: APIServerLog -> String
$cshowList :: [APIServerLog] -> ShowS
showList :: [APIServerLog] -> ShowS
Show, (forall x. APIServerLog -> Rep APIServerLog x)
-> (forall x. Rep APIServerLog x -> APIServerLog)
-> Generic APIServerLog
forall x. Rep APIServerLog x -> APIServerLog
forall x. APIServerLog -> Rep APIServerLog x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. APIServerLog -> Rep APIServerLog x
from :: forall x. APIServerLog -> Rep APIServerLog x
$cto :: forall x. Rep APIServerLog x -> APIServerLog
to :: forall x. Rep APIServerLog x -> APIServerLog
Generic)
  deriving anyclass ([APIServerLog] -> Value
[APIServerLog] -> Encoding
APIServerLog -> Bool
APIServerLog -> Value
APIServerLog -> Encoding
(APIServerLog -> Value)
-> (APIServerLog -> Encoding)
-> ([APIServerLog] -> Value)
-> ([APIServerLog] -> Encoding)
-> (APIServerLog -> Bool)
-> ToJSON APIServerLog
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: APIServerLog -> Value
toJSON :: APIServerLog -> Value
$ctoEncoding :: APIServerLog -> Encoding
toEncoding :: APIServerLog -> Encoding
$ctoJSONList :: [APIServerLog] -> Value
toJSONList :: [APIServerLog] -> Value
$ctoEncodingList :: [APIServerLog] -> Encoding
toEncodingList :: [APIServerLog] -> Encoding
$comitField :: APIServerLog -> Bool
omitField :: APIServerLog -> Bool
ToJSON)

-- | New type wrapper to define JSON instances.
newtype PathInfo = PathInfo ByteString
  deriving stock (PathInfo -> PathInfo -> Bool
(PathInfo -> PathInfo -> Bool)
-> (PathInfo -> PathInfo -> Bool) -> Eq PathInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PathInfo -> PathInfo -> Bool
== :: PathInfo -> PathInfo -> Bool
$c/= :: PathInfo -> PathInfo -> Bool
/= :: PathInfo -> PathInfo -> Bool
Eq, Int -> PathInfo -> ShowS
[PathInfo] -> ShowS
PathInfo -> String
(Int -> PathInfo -> ShowS)
-> (PathInfo -> String) -> ([PathInfo] -> ShowS) -> Show PathInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PathInfo -> ShowS
showsPrec :: Int -> PathInfo -> ShowS
$cshow :: PathInfo -> String
show :: PathInfo -> String
$cshowList :: [PathInfo] -> ShowS
showList :: [PathInfo] -> ShowS
Show)

instance ToJSON PathInfo where
  toJSON :: PathInfo -> Value
toJSON (PathInfo ByteString
bytes) =
    Text -> Value
Aeson.String (Text -> Value) -> Text -> Value
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 ByteString
bytes

-- | New type wrapper to define JSON instances.
--
-- NOTE: We are not using http-types 'StdMethod' as we do not want to be
-- constrained in terms of logging and accept any method in a 'Request'.
newtype Method = Method ByteString
  deriving stock (Method -> Method -> Bool
(Method -> Method -> Bool)
-> (Method -> Method -> Bool) -> Eq Method
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Method -> Method -> Bool
== :: Method -> Method -> Bool
$c/= :: Method -> Method -> Bool
/= :: Method -> Method -> Bool
Eq, Int -> Method -> ShowS
[Method] -> ShowS
Method -> String
(Int -> Method -> ShowS)
-> (Method -> String) -> ([Method] -> ShowS) -> Show Method
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Method -> ShowS
showsPrec :: Int -> Method -> ShowS
$cshow :: Method -> String
show :: Method -> String
$cshowList :: [Method] -> ShowS
showList :: [Method] -> ShowS
Show)

instance ToJSON Method where
  toJSON :: Method -> Value
toJSON (Method ByteString
bytes) =
    Text -> Value
Aeson.String (Text -> Value) -> Text -> Value
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 ByteString
bytes