{-# LANGUAGE QuasiQuotes                #-}
{-# LANGUAGE RecordWildCards            #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE BangPatterns               #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE DeriveDataTypeable         #-}
{-# LANGUAGE StandaloneDeriving         #-}
{-# LANGUAGE ExistentialQuantification  #-}
{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DeriveDataTypeable         #-}
{-# LANGUAGE RecordWildCards            #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE StandaloneDeriving         #-}
{-# LANGUAGE TypeSynonymInstances       #-}
{-# LANGUAGE FlexibleInstances          #-}

module Data.KeyStore.Types.PasswordStoreModel where

import qualified Control.Lens               as L
import           Data.Aeson
import           Data.API.JSON
import           Data.KeyStore.Types.PasswordStoreSchema
import qualified Data.Map                                 as Map
import           Data.API.Tools
import           Data.Time
import           Data.KeyStore.Types.UTC


$(generate passwordStoreSchema)
$(generateAPITools passwordStoreSchema
                   [ enumTool
                   , jsonTool'
                   , lensTool
                   ])


instance ToJSON PasswordStore where
  toJSON :: PasswordStore -> Value
toJSON = PasswordStore_ -> Value
forall a. ToJSON a => a -> Value
toJSON (PasswordStore_ -> Value)
-> (PasswordStore -> PasswordStore_) -> PasswordStore -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PasswordStore -> PasswordStore_
toPasswordStore_

instance FromJSON PasswordStore where
  parseJSON :: Value -> Parser PasswordStore
parseJSON = (PasswordStore_ -> PasswordStore)
-> Parser PasswordStore_ -> Parser PasswordStore
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PasswordStore_ -> PasswordStore
fromPasswordStore_ (Parser PasswordStore_ -> Parser PasswordStore)
-> (Value -> Parser PasswordStore_)
-> Value
-> Parser PasswordStore
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser PasswordStore_
forall a. FromJSON a => Value -> Parser a
parseJSON

instance FromJSONWithErrs PasswordStore where
  parseJSONWithErrs :: Value -> ParserWithErrs PasswordStore
parseJSONWithErrs = (PasswordStore_ -> PasswordStore)
-> ParserWithErrs PasswordStore_ -> ParserWithErrs PasswordStore
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PasswordStore_ -> PasswordStore
fromPasswordStore_ (ParserWithErrs PasswordStore_ -> ParserWithErrs PasswordStore)
-> (Value -> ParserWithErrs PasswordStore_)
-> Value
-> ParserWithErrs PasswordStore
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> ParserWithErrs PasswordStore_
forall a. FromJSONWithErrs a => Value -> ParserWithErrs a
parseJSONWithErrs


data PasswordStore =
  PasswordStore
    { PasswordStore -> PasswordStoreComment
_ps_comment :: PasswordStoreComment
    , PasswordStore -> PasswordMap
_ps_map     :: PasswordMap
    , PasswordStore -> UTCTime
_ps_setup   :: UTCTime
    }
  deriving (Int -> PasswordStore -> ShowS
[PasswordStore] -> ShowS
PasswordStore -> String
(Int -> PasswordStore -> ShowS)
-> (PasswordStore -> String)
-> ([PasswordStore] -> ShowS)
-> Show PasswordStore
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PasswordStore] -> ShowS
$cshowList :: [PasswordStore] -> ShowS
show :: PasswordStore -> String
$cshow :: PasswordStore -> String
showsPrec :: Int -> PasswordStore -> ShowS
$cshowsPrec :: Int -> PasswordStore -> ShowS
Show,PasswordStore -> PasswordStore -> Bool
(PasswordStore -> PasswordStore -> Bool)
-> (PasswordStore -> PasswordStore -> Bool) -> Eq PasswordStore
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PasswordStore -> PasswordStore -> Bool
$c/= :: PasswordStore -> PasswordStore -> Bool
== :: PasswordStore -> PasswordStore -> Bool
$c== :: PasswordStore -> PasswordStore -> Bool
Eq)

toPasswordStore_ :: PasswordStore -> PasswordStore_
toPasswordStore_ :: PasswordStore -> PasswordStore_
toPasswordStore_ PasswordStore{UTCTime
PasswordMap
PasswordStoreComment
_ps_setup :: UTCTime
_ps_map :: PasswordMap
_ps_comment :: PasswordStoreComment
_ps_setup :: PasswordStore -> UTCTime
_ps_map :: PasswordStore -> PasswordMap
_ps_comment :: PasswordStore -> PasswordStoreComment
..} =
  PasswordStore_ :: PasswordStoreComment -> PasswordMap_ -> UTC -> PasswordStore_
PasswordStore_
    { _z_ps_comment :: PasswordStoreComment
_z_ps_comment =                PasswordStoreComment
_ps_comment
    , _z_ps_map :: PasswordMap_
_z_ps_map     = PasswordMap -> PasswordMap_
toPasswordMap_ PasswordMap
_ps_map
    , _z_ps_setup :: UTC
_z_ps_setup   = UTCTime -> UTC
UTC            UTCTime
_ps_setup
    }

fromPasswordStore_ :: PasswordStore_ -> PasswordStore
fromPasswordStore_ :: PasswordStore_ -> PasswordStore
fromPasswordStore_ PasswordStore_{UTC
PasswordStoreComment
PasswordMap_
_z_ps_setup :: UTC
_z_ps_map :: PasswordMap_
_z_ps_comment :: PasswordStoreComment
_z_ps_setup :: PasswordStore_ -> UTC
_z_ps_map :: PasswordStore_ -> PasswordMap_
_z_ps_comment :: PasswordStore_ -> PasswordStoreComment
..} =
  PasswordStore :: PasswordStoreComment -> PasswordMap -> UTCTime -> PasswordStore
PasswordStore
    { _ps_comment :: PasswordStoreComment
_ps_comment =                  PasswordStoreComment
_z_ps_comment
    , _ps_map :: PasswordMap
_ps_map     = PasswordMap_ -> PasswordMap
fromPasswordMap_ PasswordMap_
_z_ps_map
    , _ps_setup :: UTCTime
_ps_setup   = UTC -> UTCTime
_UTC             UTC
_z_ps_setup
    }


-- The PasswordStre and SessionMap association lists are represented internally
-- with maps.


type PasswordMap = Map.Map PasswordName Password

toPasswordMap_ :: PasswordMap -> PasswordMap_
toPasswordMap_ :: PasswordMap -> PasswordMap_
toPasswordMap_ PasswordMap
mp = [NamePasswordAssoc_] -> PasswordMap_
PasswordMap_ ([NamePasswordAssoc_] -> PasswordMap_)
-> [NamePasswordAssoc_] -> PasswordMap_
forall a b. (a -> b) -> a -> b
$
  [ PasswordName -> Password_ -> NamePasswordAssoc_
NamePasswordAssoc_ PasswordName
nm (Password_ -> NamePasswordAssoc_)
-> Password_ -> NamePasswordAssoc_
forall a b. (a -> b) -> a -> b
$ Password -> Password_
toPassword_ Password
pw
    | (PasswordName
nm,Password
pw) <- PasswordMap -> [(PasswordName, Password)]
forall k a. Map k a -> [(k, a)]
Map.assocs PasswordMap
mp
    ]

fromPasswordMap_ :: PasswordMap_ -> PasswordMap
fromPasswordMap_ :: PasswordMap_ -> PasswordMap
fromPasswordMap_ PasswordMap_
mp_ = [(PasswordName, Password)] -> PasswordMap
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
  [ (PasswordName
_z_npa_name,Password_ -> Password
fromPassword_ Password_
_z_npa_password)
    | NamePasswordAssoc_{PasswordName
Password_
_z_npa_password :: Password_
_z_npa_name :: PasswordName
_z_npa_password :: NamePasswordAssoc_ -> Password_
_z_npa_name :: NamePasswordAssoc_ -> PasswordName
..} <- PasswordMap_ -> [NamePasswordAssoc_]
_z_pm_map PasswordMap_
mp_
    ]


data Password =
  Password
    { Password -> PasswordName
_pw_name        :: PasswordName
    , Password -> PasswordText
_pw_text        :: PasswordText
    , Password -> SessionMap
_pw_sessions    :: SessionMap
    , Password -> Bool
_pw_isOneShot   :: Bool
    , Password -> Bool
_pw_primed      :: Bool
    , Password -> UTCTime
_pw_setup       :: UTCTime
    }
  deriving (Int -> Password -> ShowS
[Password] -> ShowS
Password -> String
(Int -> Password -> ShowS)
-> (Password -> String) -> ([Password] -> ShowS) -> Show Password
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Password] -> ShowS
$cshowList :: [Password] -> ShowS
show :: Password -> String
$cshow :: Password -> String
showsPrec :: Int -> Password -> ShowS
$cshowsPrec :: Int -> Password -> ShowS
Show,Password -> Password -> Bool
(Password -> Password -> Bool)
-> (Password -> Password -> Bool) -> Eq Password
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Password -> Password -> Bool
$c/= :: Password -> Password -> Bool
== :: Password -> Password -> Bool
$c== :: Password -> Password -> Bool
Eq)

toPassword_ :: Password -> Password_
toPassword_ :: Password -> Password_
toPassword_ Password{Bool
UTCTime
SessionMap
PasswordText
PasswordName
_pw_setup :: UTCTime
_pw_primed :: Bool
_pw_isOneShot :: Bool
_pw_sessions :: SessionMap
_pw_text :: PasswordText
_pw_name :: PasswordName
_pw_setup :: Password -> UTCTime
_pw_primed :: Password -> Bool
_pw_isOneShot :: Password -> Bool
_pw_sessions :: Password -> SessionMap
_pw_text :: Password -> PasswordText
_pw_name :: Password -> PasswordName
..} =
  Password_ :: PasswordName
-> PasswordText -> SessionMap_ -> Bool -> Bool -> UTC -> Password_
Password_
    { _z_pw_name :: PasswordName
_z_pw_name        =               PasswordName
_pw_name
    , _z_pw_text :: PasswordText
_z_pw_text        =               PasswordText
_pw_text
    , _z_pw_sessions :: SessionMap_
_z_pw_sessions    = SessionMap -> SessionMap_
toSessionMap_ SessionMap
_pw_sessions
    , _z_pw_isOneShot :: Bool
_z_pw_isOneShot   =               Bool
_pw_isOneShot
    , _z_pw_primed :: Bool
_z_pw_primed      =               Bool
_pw_primed
    , _z_pw_setup :: UTC
_z_pw_setup       = UTCTime -> UTC
UTC           UTCTime
_pw_setup
    }

fromPassword_ :: Password_ -> Password
fromPassword_ :: Password_ -> Password
fromPassword_ Password_{Bool
UTC
PasswordText
PasswordName
SessionMap_
_z_pw_setup :: UTC
_z_pw_primed :: Bool
_z_pw_isOneShot :: Bool
_z_pw_sessions :: SessionMap_
_z_pw_text :: PasswordText
_z_pw_name :: PasswordName
_z_pw_setup :: Password_ -> UTC
_z_pw_primed :: Password_ -> Bool
_z_pw_isOneShot :: Password_ -> Bool
_z_pw_sessions :: Password_ -> SessionMap_
_z_pw_text :: Password_ -> PasswordText
_z_pw_name :: Password_ -> PasswordName
..} =
  Password :: PasswordName
-> PasswordText
-> SessionMap
-> Bool
-> Bool
-> UTCTime
-> Password
Password
    { _pw_name :: PasswordName
_pw_name        =                 PasswordName
_z_pw_name
    , _pw_text :: PasswordText
_pw_text        =                 PasswordText
_z_pw_text
    , _pw_sessions :: SessionMap
_pw_sessions    = SessionMap_ -> SessionMap
fromSessionMap_ SessionMap_
_z_pw_sessions
    , _pw_isOneShot :: Bool
_pw_isOneShot   =                 Bool
_z_pw_isOneShot
    , _pw_primed :: Bool
_pw_primed      =                 Bool
_z_pw_primed
    , _pw_setup :: UTCTime
_pw_setup       = UTC -> UTCTime
_UTC            UTC
_z_pw_setup
    }


type SessionMap = Map.Map SessionName Session

toSessionMap_ :: SessionMap -> SessionMap_
toSessionMap_ :: SessionMap -> SessionMap_
toSessionMap_ SessionMap
mp = [SessionPasswordAssoc_] -> SessionMap_
SessionMap_ ([SessionPasswordAssoc_] -> SessionMap_)
-> [SessionPasswordAssoc_] -> SessionMap_
forall a b. (a -> b) -> a -> b
$
  [ SessionName -> Session -> SessionPasswordAssoc_
SessionPasswordAssoc_ SessionName
nm Session
ssn
    | (SessionName
nm,Session
ssn) <- SessionMap -> [(SessionName, Session)]
forall k a. Map k a -> [(k, a)]
Map.assocs SessionMap
mp
    ]

fromSessionMap_ :: SessionMap_ -> SessionMap
fromSessionMap_ :: SessionMap_ -> SessionMap
fromSessionMap_ SessionMap_
mp_ = [(SessionName, Session)] -> SessionMap
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
  [ (SessionName
_z_spa_name,Session
_z_spa_session)
    | SessionPasswordAssoc_{SessionName
Session
_z_spa_session :: Session
_z_spa_name :: SessionName
_z_spa_session :: SessionPasswordAssoc_ -> Session
_z_spa_name :: SessionPasswordAssoc_ -> SessionName
..} <- SessionMap_ -> [SessionPasswordAssoc_]
_z_smp_map SessionMap_
mp_
    ]


L.makeLenses ''PasswordStore
L.makeLenses ''Password