{-# LANGUAGE MultiParamTypeClasses #-}

module Util where

import           Control.Monad.Except
import           Control.Monad.Reader
import           Data.Time
import           Hedgehog             (Gen)
import qualified Hedgehog.Gen         as Gen
import qualified Hedgehog.Range       as Range
import           Web.JWT.ASAP

newtype PureEnv a =
  PureEnv { runPureEnv :: ReaderT [(String, String)] (Either AsapError) a }

runWithEnv :: PureEnv a -> [(String, String)] -> Either AsapError a
runWithEnv =
  runReaderT . runPureEnv

instance Functor PureEnv where
  fmap f =
    PureEnv . fmap f . runPureEnv

instance Applicative PureEnv where
  pure =
    PureEnv . pure
  f <*> fa =
    PureEnv (runPureEnv f <*> runPureEnv fa)

instance Monad PureEnv where
  fa >>= f =
    PureEnv (runPureEnv fa >>= runPureEnv . f)

instance MonadError AsapError PureEnv where
  throwError =
    PureEnv . throwError
  catchError fa f =
    PureEnv (catchError (runPureEnv fa) (runPureEnv . f))

instance MonadEnv PureEnv where
  lookupEnv' s =
    PureEnv (ReaderT (pure . lookup s))

exampleDataUri :: String
exampleDataUri =
  "data:application/pkcs8;kid=haskell-asap-test;base64,MIIEvQIBADANBgkqhkiG9w0BAQEF\
  \AASCBKcwggSjAgEAAoIBAQC/1EaVWX/IopFgxptgkduG0a5IC3PTyvhKtvxXhOCCGueL0dpMunAAKzsy\
  \xCSJsU3DQWMu3xeH+aqPI2aIklLBTqKkPcYxLT+Q99i1cZITfCGRwTRvBKARVf9I36EERwkjuLtnEEQi\
  \kg6kL6rC+86VPXR5RIsVCDafnc3ASR77mRc2sIoxLx40cYh2ax15tC9Z778ZFEhkFW/ZdgC5xEgnh4N3\
  \Wvano9m2d+vhbEwz/6O+WzJZvGX19fsNHamEyfil+pfb28FE6GxQxqfV1PTtNPz1xMgw1rBZJRZ6Gnsr\
  \Z+lQVU3eU1f1Rt1kbW9T9hkoQ3RgiYS1Fl841A4nEhrnAgMBAAECggEAETkBzU7nxh+yZbnvIVB3ITea\
  \KiW9FHrYp/yd002+ym+X8lm4+8KRY7J98iTiEuq0TJ+GRCMLfc3QnmFTR1e7zlc9Cvnw3WFun5lg/4le\
  \0BkI+okaKA2GQYgzD1vknPmzvF1NlgdD1sa+Qcd10WPCPGv0FR8uTYkbPmFwo57tBTGlVao/8NYFClfA\
  \PUqA2Ghb5tHtYELwIOlWqBTVkNQf5sEV8okApFjtkjxP3pO8YD3uPUG0kdghqnlbQaA1UXDKbLmh+NQF\
  \lF1tw2Dri8s9yzOdr1ujALdEcoKCmbWPXDvxZsu/xiUCpWCtmtUeyZAT+LA6t5cFykAXqrXdN4KEAQKB\
  \gQD+E3DVJEElxcrozzcgtsoiPZd38gD57kgF6C3VtdTzHA4ZMGoX8eF8TXUoisAEfhfnkcx2/HUu1DXI\
  \58SI37LpIPeJYyv36GwzeuS3cr5NtGaEXp+u/YE8Eft5FGgeXR8W2/wyOFoYzjoNt//SvzmabPo63Vwk\
  \jxgwXBYPOulpZwKBgQDBSClcgiQvwibFuHyjtGrSJlvsj6eQbLBekZY8hSqlJeJTUkxyOtMpldQ0gdmS\
  \5J6IsjdJ6mMU6Il5iwF2Mk/M+UMoHvlMCrvTKoThCo8wFAZL6LVEhNsPQzSHzs38qZgb81dBgTgJnvyr\
  \q50NPI1EDLlTn/2hh15WxHw3EydSgQKBgQDhiOJM4UzPOd9ff6lg6cFOWbwd5f2F3kWisLIXFbx9PTcq\
  \lvZmYPkWvS81mMzQcBnKHnsQWBOxSQChYVLtaR1IolH5a8X43yFFJV7nlPxmv6+M6u32iONyLkg696lg\
  \4qqZQReCgNFBWbbgvKdjLQn2EayiGiMT9M21B9kxFctiGwKBgC3KELJvym7eCh1xVWXbCit7Fu/2IHZg\
  \qW/eAb+YtL+nN/URXDb7pKcHbdx6nrbkHoK35c1HD+4WIOuAePotdSZULwrEO78+E701J4HA5Kc5Nzyo\
  \hrkS2GrHOxypa7dd3kFQ5u0H1eTBm453+571J2plsUoUbxvjXAAmUF8j1H8BAoGAYNycYkiZeTt9AN4S\
  \PK5N75HlAsi5iT6kRh90nFtKIAR9V0SNEeA3MnrCKdF22mNaQBbiDOu0fmdyNLRz0dp7nu3Bp7JZ6KvP\
  \tARzFTtgRrz41jCT2F+1R5zYdwK2LnTkjPIAdDL3/oeywaYPr9HIqYLzod2jh4KhZVttg1EpT2k="

nominalYear :: NominalDiffTime
nominalYear =
  nominalDay * 365

nominalDecade :: NominalDiffTime
nominalDecade =
  nominalYear * 10

genInDecade :: Gen NominalDiffTime
genInDecade =
  Gen.realFrac_ (Range.constant 0 nominalDecade)

genMaxAge :: Gen MaxAge
genMaxAge =
  MaxAge <$> Gen.realFrac_ (Range.constant 0 (9 * 60))
