module TestUtils.SessionId
  ( getSessionId
  ) where

import           Control.Exception     (tryJust)
import           Control.Monad         (guard)
import           Data.Time             (getCurrentTime)
import           Data.Time.Clock       (nominalDiffTimeToSeconds)
import           Data.Time.Clock.POSIX (utcTimeToPOSIXSeconds)
import           System.Environment    (getEnv)
import           System.IO.Error       (isDoesNotExistError)

-- Create a unique ID based on the GitLab environmental variable $CI_PIPELINE_ID
-- if one is defined, otherwise the computation fails with `isDoesNotExistError`
getCIPipelineId :: IO String
getCIPipelineId :: IO String
getCIPipelineId = String -> IO String
getEnv String
"CI_PIPELINE_ID"

-- Use the value of `getCIPipelineId` if it was able to be obtained, otherwise use
-- the number of seconds since the epoch as a fallback
getSessionId :: IO String
getSessionId :: IO String
getSessionId = do
  Either () String
r <- forall e b a.
Exception e =>
(e -> Maybe b) -> IO a -> IO (Either b a)
tryJust (forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall b c a. (b -> c) -> (a -> b) -> a -> c
. IOError -> Bool
isDoesNotExistError) IO String
getCIPipelineId
  case Either () String
r of
    Left ()
e -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
      (forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (RealFrac a, Integral b) => a -> b
floor forall b c a. (b -> c) -> (a -> b) -> a -> c
. NominalDiffTime -> Pico
nominalDiffTimeToSeconds forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> NominalDiffTime
utcTimeToPOSIXSeconds)
      IO UTCTime
getCurrentTime
    Right String
v -> IO String
getCIPipelineId