{-# LANGUAGE CPP                     #-}
{-# LANGUAGE DataKinds               #-}
{-# LANGUAGE FlexibleContexts        #-}
{-# LANGUAGE FlexibleInstances       #-}
{-# LANGUAGE MultiParamTypeClasses   #-}
{-# LANGUAGE TypeFamilies            #-}
{-# LANGUAGE UndecidableInstances    #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Network.HTTP.ApiMaker.SessionState
  ( SessionState(..)
  , Session(..)
  , emptySession
  ) where

import           Control.Lens
import qualified Data.ByteString.Char8 as B
import qualified Network.HTTP.Client   as C

-- | Session state contract.
class SessionState st where
  csrfToken :: Lens' st (Maybe B.ByteString)
  sessionData :: Lens' st (Maybe B.ByteString)
  cookieJarData :: Lens' st (Maybe C.CookieJar)


-- | Simple session state. This probably is sufficient for the day-to-day use.
data Session = Session
   --  { unSession :: C.CookieJar }   -- TODO: Does not work? Bug in req library?
  { Session -> Maybe ByteString
sessCsrfToken     :: Maybe B.ByteString
  , Session -> Maybe ByteString
sessSessionData   :: Maybe B.ByteString
  , Session -> Maybe CookieJar
sessCookieJarData :: Maybe C.CookieJar
  } deriving (Int -> Session -> ShowS
[Session] -> ShowS
Session -> String
(Int -> Session -> ShowS)
-> (Session -> String) -> ([Session] -> ShowS) -> Show Session
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Session] -> ShowS
$cshowList :: [Session] -> ShowS
show :: Session -> String
$cshow :: Session -> String
showsPrec :: Int -> Session -> ShowS
$cshowsPrec :: Int -> Session -> ShowS
Show)

-- | Simple session state implemention.
instance SessionState Session where
  csrfToken :: (Maybe ByteString -> f (Maybe ByteString)) -> Session -> f Session
csrfToken = (Session -> Maybe ByteString)
-> (Session -> Maybe ByteString -> Session)
-> Lens' Session (Maybe ByteString)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Session -> Maybe ByteString
sessCsrfToken (\Session
sess Maybe ByteString
c' -> Session
sess {sessCsrfToken :: Maybe ByteString
sessCsrfToken = Maybe ByteString
c'})
  sessionData :: (Maybe ByteString -> f (Maybe ByteString)) -> Session -> f Session
sessionData = (Session -> Maybe ByteString)
-> (Session -> Maybe ByteString -> Session)
-> Lens' Session (Maybe ByteString)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Session -> Maybe ByteString
sessSessionData (\Session
sess Maybe ByteString
d' -> Session
sess {sessSessionData :: Maybe ByteString
sessSessionData = Maybe ByteString
d'})
  cookieJarData :: (Maybe CookieJar -> f (Maybe CookieJar)) -> Session -> f Session
cookieJarData = (Session -> Maybe CookieJar)
-> (Session -> Maybe CookieJar -> Session)
-> Lens' Session (Maybe CookieJar)
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Session -> Maybe CookieJar
sessCookieJarData (\Session
sess Maybe CookieJar
d' -> Session
sess {sessCookieJarData :: Maybe CookieJar
sessCookieJarData = Maybe CookieJar
d'})


-- | Empty session state.
emptySession :: Session
emptySession :: Session
emptySession = Maybe ByteString -> Maybe ByteString -> Maybe CookieJar -> Session
Session Maybe ByteString
forall a. Maybe a
Nothing Maybe ByteString
forall a. Maybe a
Nothing Maybe CookieJar
forall a. Maybe a
Nothing