{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Data.GenValidity.Appendful.Collection where

import Control.Monad
import Data.Appendful
import Data.GenValidity
import Data.GenValidity.Containers ()
import Data.GenValidity.Time ()
import Data.Map (Map)
import qualified Data.Map as M
import Data.Set (Set)
import qualified Data.Set as S
import Test.QuickCheck

instance GenValid ClientId where
  genValid :: Gen ClientId
genValid = forall a. (Generic a, GGenValid (Rep a)) => Gen a
genValidStructurallyWithoutExtraChecking
  shrinkValid :: ClientId -> [ClientId]
shrinkValid = forall a.
(Generic a, GValidRecursivelyShrink (Rep a),
 GValidSubterms (Rep a) a) =>
a -> [a]
shrinkValidStructurallyWithoutExtraFiltering

instance (GenValid ci, GenValid si, GenValid a, Show ci, Show si, Show a, Ord ci, Ord si, Ord a) => GenValid (ClientStore ci si a) where
  genValid :: Gen (ClientStore ci si a)
genValid =
    forall a. (Int -> Gen a) -> Gen a
sized forall a b. (a -> b) -> a -> b
$ \Int
n -> do
      (Int
a, Int
b) <- Int -> Gen (Int, Int)
genSplit Int
n
      Set si
s <- forall a. Int -> Gen a -> Gen a
resize Int
a forall a. GenValid a => Gen a
genValid
      Map ci a
clientStoreAdded <- forall a. Int -> Gen a -> Gen a
resize Int
b forall a. GenValid a => Gen a
genValid
      Map si a
clientStoreSynced <- forall i a. (Ord i, GenValid a) => Set i -> Gen (Map i a)
mapWithIds Set si
s
      forall (f :: * -> *) a. Applicative f => a -> f a
pure ClientStore {Map ci a
Map si a
clientStoreAdded :: Map ci a
clientStoreSynced :: Map si a
clientStoreSynced :: Map si a
clientStoreAdded :: Map ci a
..}
  shrinkValid :: ClientStore ci si a -> [ClientStore ci si a]
shrinkValid = forall a.
(Validity a, Generic a, GValidRecursivelyShrink (Rep a),
 GValidSubterms (Rep a) a) =>
a -> [a]
shrinkValidStructurally

instance (GenValid ci, GenValid si, GenValid a, Show ci, Show si, Show a, Ord ci, Ord si, Ord a) => GenValid (SyncRequest ci si a) where
  genValid :: Gen (SyncRequest ci si a)
genValid = do
    Map ci a
syncRequestAdded <- forall a. GenValid a => Gen a
genValid
    Maybe si
syncRequestMaximumSynced <- forall a. GenValid a => Gen a
genValid
    forall (f :: * -> *) a. Applicative f => a -> f a
pure SyncRequest {Maybe si
Map ci a
syncRequestAdded :: Map ci a
syncRequestMaximumSynced :: Maybe si
syncRequestMaximumSynced :: Maybe si
syncRequestAdded :: Map ci a
..}
  shrinkValid :: SyncRequest ci si a -> [SyncRequest ci si a]
shrinkValid = forall a.
(Validity a, Generic a, GValidRecursivelyShrink (Rep a),
 GValidSubterms (Rep a) a) =>
a -> [a]
shrinkValidStructurally

instance (GenValid ci, GenValid si, GenValid a, Show ci, Show si, Show a, Ord ci, Ord si, Ord a) => GenValid (SyncResponse ci si a) where
  genValid :: Gen (SyncResponse ci si a)
genValid = do
    (Set si
s1, Set si
s2) <- forall a. GenValid a => Gen a
genValid forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall i. Ord i => Set i -> Gen (Set i, Set i)
splitSet
    Map ci si
syncResponseClientAdded <-
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k a. Ord k => [(k, a)] -> Map k a
M.fromList forall a b. (a -> b) -> a -> b
$
        forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (forall a. Set a -> [a]
S.toList Set si
s1) forall a b. (a -> b) -> a -> b
$
          \si
i -> do
            ci
cid <- forall a. GenValid a => Gen a
genValid -- TODO maybe we can find a way to not generate duplicate client ids and speed up this generator, but it's fine for now.
            forall (f :: * -> *) a. Applicative f => a -> f a
pure (ci
cid, si
i)
    Map si a
syncResponseServerAdded <- forall i a. (Ord i, GenValid a) => Set i -> Gen (Map i a)
mapWithIds Set si
s2
    forall (f :: * -> *) a. Applicative f => a -> f a
pure SyncResponse {Map ci si
Map si a
syncResponseClientAdded :: Map ci si
syncResponseServerAdded :: Map si a
syncResponseServerAdded :: Map si a
syncResponseClientAdded :: Map ci si
..}
  shrinkValid :: SyncResponse ci si a -> [SyncResponse ci si a]
shrinkValid = forall a.
(Validity a, Generic a, GValidRecursivelyShrink (Rep a),
 GValidSubterms (Rep a) a) =>
a -> [a]
shrinkValidStructurally

splitSet :: Ord i => Set i -> Gen (Set i, Set i)
splitSet :: forall i. Ord i => Set i -> Gen (Set i, Set i)
splitSet Set i
s =
  if forall a. Set a -> Bool
S.null Set i
s
    then forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Set a
S.empty, forall a. Set a
S.empty)
    else do
      i
a <- forall a. [a] -> Gen a
elements forall a b. (a -> b) -> a -> b
$ forall a. Set a -> [a]
S.toList Set i
s
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> Set a -> (Set a, Set a)
S.split i
a Set i
s

mapWithIds :: (Ord i, GenValid a) => Set i -> Gen (Map i a)
mapWithIds :: forall i a. (Ord i, GenValid a) => Set i -> Gen (Map i a)
mapWithIds = forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. (k -> a) -> Set k -> Map k a
M.fromSet (forall a b. a -> b -> a
const forall a. GenValid a => Gen a
genValid)

instance (GenValid si, GenValid a, Show si, Show a, Ord si, Ord a) => GenValid (ServerStore si a) where
  genValid :: Gen (ServerStore si a)
genValid = forall a. (Generic a, GGenValid (Rep a)) => Gen a
genValidStructurallyWithoutExtraChecking
  shrinkValid :: ServerStore si a -> [ServerStore si a]
shrinkValid = forall a.
(Generic a, GValidRecursivelyShrink (Rep a),
 GValidSubterms (Rep a) a) =>
a -> [a]
shrinkValidStructurallyWithoutExtraFiltering

genServerStoreFromSet :: (Ord si, GenValid v) => Set si -> Gen (ServerStore si v)
genServerStoreFromSet :: forall si v.
(Ord si, GenValid v) =>
Set si -> Gen (ServerStore si v)
genServerStoreFromSet Set si
s = forall si a. Map si a -> ServerStore si a
ServerStore forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall i a. (Ord i, GenValid a) => Set i -> Gen (Map i a)
mapWithIds Set si
s

genUnsyncedStore ::
  forall ci si a.
  (Show ci, Ord ci, Ord si, Ord a, GenValid ci, GenValid si, GenValid a) =>
  Gen (ClientStore ci si a)
genUnsyncedStore :: forall ci si a.
(Show ci, Ord ci, Ord si, Ord a, GenValid ci, GenValid si,
 GenValid a) =>
Gen (ClientStore ci si a)
genUnsyncedStore = do
  Map ci a
as <- forall a. GenValid a => Gen a
genValid
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall ci si a. ClientStore ci si a
emptyClientStore {clientStoreAdded :: Map ci a
clientStoreAdded = Map ci a
as}

genClientStoreFromSet :: (Show ci, Ord ci, Ord si, GenValid ci, GenValid v) => Set si -> Gen (ClientStore ci si v)
genClientStoreFromSet :: forall ci si v.
(Show ci, Ord ci, Ord si, GenValid ci, GenValid v) =>
Set si -> Gen (ClientStore ci si v)
genClientStoreFromSet Set si
s = do
  Map ci v
clientStoreAdded <- forall a. GenValid a => Gen a
genValid
  Map si v
clientStoreSynced <- forall i a. (Ord i, GenValid a) => Set i -> Gen (Map i a)
mapWithIds Set si
s
  forall (f :: * -> *) a. Applicative f => a -> f a
pure ClientStore {Map ci v
Map si v
clientStoreSynced :: Map si v
clientStoreAdded :: Map ci v
clientStoreAdded :: Map ci v
clientStoreSynced :: Map si v
..}