{-# 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 = forall a. ToJSON a => a -> Value
toJSON forall b c a. (b -> c) -> (a -> b) -> a -> c
. PasswordStore -> PasswordStore_
toPasswordStore_

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

instance FromJSONWithErrs PasswordStore where
  parseJSONWithErrs :: Value -> ParserWithErrs PasswordStore
parseJSONWithErrs = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PasswordStore_ -> PasswordStore
fromPasswordStore_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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
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
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_
    { _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
    { _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_ forall a b. (a -> b) -> a -> b
$
  [ PasswordName -> Password_ -> NamePasswordAssoc_
NamePasswordAssoc_ PasswordName
nm forall a b. (a -> b) -> a -> b
$ Password -> Password_
toPassword_ Password
pw
    | (PasswordName
nm,Password
pw) <- forall k a. Map k a -> [(k, a)]
Map.assocs PasswordMap
mp
    ]

fromPasswordMap_ :: PasswordMap_ -> PasswordMap
fromPasswordMap_ :: PasswordMap_ -> PasswordMap
fromPasswordMap_ PasswordMap_
mp_ = 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
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
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_
    { _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
    { _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_ forall a b. (a -> b) -> a -> b
$
  [ SessionName -> Session -> SessionPasswordAssoc_
SessionPasswordAssoc_ SessionName
nm Session
ssn
    | (SessionName
nm,Session
ssn) <- forall k a. Map k a -> [(k, a)]
Map.assocs SessionMap
mp
    ]

fromSessionMap_ :: SessionMap_ -> SessionMap
fromSessionMap_ :: SessionMap_ -> SessionMap
fromSessionMap_ SessionMap_
mp_ = 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