module Model.Tokens.UploadSpec where

import TestImport
import Model.Tokens.Upload

import Model.TypesSpec ()

import Utils.Lens

import qualified Crypto.Saltine.Core.SecretBox as SecretBox

import System.IO.Unsafe


instance Arbitrary UploadToken where
  arbitrary = UploadToken
    <$> arbitrary
    <*> arbitrary
    <*> fmap (over _utctDayTime $ fromInteger . round) arbitrary
    <*> arbitrary
    <*> arbitrary
    <*> fmap (over (mapped . _utctDayTime) $ fromInteger . round) arbitrary
    <*> fmap (over (mapped . _utctDayTime) $ fromInteger . round) arbitrary
    <*> arbitrary
    <*> arbitrary

instance Arbitrary UploadTokenState where
  arbitrary = genericArbitrary
  shrink = genericShrink

instance Arbitrary UploadTokenStateHashState where
  arbitrary = do
    let key = unsafePerformIO SecretBox.newKey
        utsHashStateNonce = unsafePerformIO SecretBox.newNonce
    plaintext <- arbitrary
    let utsHashStateState = SecretBox.secretbox key utsHashStateNonce plaintext
    return UploadTokenStateHashState{..}

spec :: Spec
spec = do
  parallel $ do
    lawsCheckHspec (Proxy @UploadToken)
      [ eqLaws, ordLaws, showLaws, jsonLaws ]
    lawsCheckHspec (Proxy @UploadTokenState)
      [ eqLaws, ordLaws, showLaws, jsonLaws ]
    lawsCheckHspec (Proxy @UploadTokenStateHashState)
      [ eqLaws, ordLaws, showLaws, jsonLaws ]
