module Snap.Snaplet.CustomAuth.Types where
import Control.Lens.TH
import Data.Binary
import Data.Binary.Orphans ()
import Data.ByteString
import Data.Text (Text)
import Data.Time.Clock (UTCTime)
import GHC.Generics (Generic)
import Network.OAuth.OAuth2 (OAuth2)
import URI.ByteString (URI)
import Snap.Core (Cookie(..))
data LoginFailure =
  NoSession | SessionRecoverFail | UsernameMissing | PasswordMissing | WrongPasswordOrUsername
  deriving (Show, Eq, Read)
data AuthFailure e =
    UserError e
  | Login LoginFailure
  | Create CreateFailure
  | Action OAuth2ActionFailure
  deriving (Show)
data CreateFailure =
    MissingName | InvalidName
  | DuplicateName
  | PasswordFailure PasswordFailure
  | OAuth2Failure OAuth2Failure
  deriving (Eq, Show, Read)
data OAuth2Failure =
    StateNotStored | StateNotReceived | ExpiredState | BadState
  | ConfigurationError | IdExtractionFailed | NoStoredToken
  | AlreadyUser | AlreadyLoggedIn
  | IdentityInUse
  | ProviderError (Maybe Text)
  | AccessTokenFetchError
  deriving (Show, Read, Eq)
data OAuth2ActionFailure =
  ActionTimeout | ActionDecodeError | ActionUserMismatch
  | AttachNotLoggedIn | AlreadyAttached
  deriving (Show, Eq, Read)
data PasswordFailure = Missing | Mismatch
  deriving (Show, Eq, Read)
data OAuth2Stage = SCallback | SLogin | SCreate | SAction
  deriving (Show, Eq, Read)
data Provider = Provider
  { providerName :: Text
  , discovery :: Maybe URI
  , scope :: Text
  , identityEndpoint :: URI
  , identityField :: Text
  , oauth :: OAuth2
  }
  deriving (Show)
data SavedAction = SavedAction
  { actionProvider :: Text
  , actionStamp :: UTCTime
  , actionUser :: Maybe ByteString
  
  
  , requireUser :: Bool
  , savedAction :: ByteString
  } deriving (Generic)
instance Binary SavedAction
data AuthUser = AuthUser
  { name :: Text
  , session :: ByteString
  , csrfToken :: ByteString
  } deriving (Show)
data AuthSettings = AuthSettings
  { _authName :: Text
  , _authSetCookie :: ByteString -> Cookie
  }
makeLenses ''AuthSettings
defAuthSettings :: AuthSettings
defAuthSettings = AuthSettings "auth" $ \x ->
  Cookie "_session" x Nothing Nothing (Just "/") False True