module Cardano.Crypto.Libsodium.Init (
  sodiumInit,
) where

import Control.Monad (unless)

import Cardano.Crypto.Libsodium.C

-- @sodiumInit@ initializes the library and should be called before any other
-- function provided by Sodium. It is safe to call this function more than once
-- and from different threads -- subsequent calls won't have any effects.
--
-- <https://libsodium.gitbook.io/doc/usage>
sodiumInit :: IO ()
sodiumInit :: IO ()
sodiumInit = do
    Int
res <- IO Int
c_sodium_init
    -- sodium_init() returns 0 on success, -1 on failure, and 1 if the library
    -- had already been initialized.
    Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
res Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
|| Int
res Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"sodium_init failed"