{-|
Module      : Botan.Low.Version
Description : Botan version info
Copyright   : (c) 2023-2024, Apotheca Labs
              (c) 2024-2025, Haskell Foundation
License     : BSD-3-Clause
Maintainer  : joris@well-typed.com, leo@apotheca.io
Stability   : experimental
Portability : POSIX

This module is based on the
[Versioning](https://botan.randombit.net/handbook/api_ref/ffi.html#versioning)
section of the C Botan FFI documentation.
-}

module Botan.Low.Version (
    botanFFIAPIVersion
  , botanFFISupportsAPI
  , botanVersionString
  , botanVersionMajor
  , botanVersionMinor
  , botanVersionPatch
  , botanVersionDatestamp
  ) where

import           Botan.Bindings.ConstPtr (ConstPtr (..))
import           Botan.Bindings.Version
import           Botan.Low.Error.Internal (throwBotanCatchingInvalidInput)
import           Botan.Low.Internal.ByteString
import           Data.ByteString (ByteString)

-- | Returns the version of the currently supported FFI API. This is expressed
-- in the form YYYYMMDD of the release date of this version of the API.
botanFFIAPIVersion :: IO Int
botanFFIAPIVersion :: IO Int
botanFFIAPIVersion = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int) -> IO Word32 -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Word32
botan_ffi_api_version

-- | Returns 'True' iff the FFI version specified is supported by this library,
-- otherwise returns 'False'.
--
-- The expression @'botanFFIAPIVersion' >>= 'botanFFISupportsAPI'@  will always
-- evaluate to 'True'. A particular version of the library may also support
-- other (older) versions of the FFI API.
botanFFISupportsAPI :: Int -> IO Bool
botanFFISupportsAPI :: Int -> IO Bool
botanFFISupportsAPI Int
version = do
    HasCallStack => IO CInt -> IO Bool
IO CInt -> IO Bool
throwBotanCatchingInvalidInput (IO CInt -> IO Bool) -> IO CInt -> IO Bool
forall a b. (a -> b) -> a -> b
$ Word32 -> IO CInt
botan_ffi_supports_api (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
version)

botanVersionString :: IO ByteString
botanVersionString :: IO ByteString
botanVersionString = IO (ConstPtr CChar)
botan_version_string IO (ConstPtr CChar)
-> (ConstPtr CChar -> IO ByteString) -> IO ByteString
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CString -> IO ByteString
peekCString (CString -> IO ByteString)
-> (ConstPtr CChar -> CString) -> ConstPtr CChar -> IO ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.unConstPtr)

-- | Returns the major version of the library
botanVersionMajor :: IO Int
botanVersionMajor :: IO Int
botanVersionMajor = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int) -> IO Word32 -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Word32
botan_version_major

-- | Returns the minor version of the library
botanVersionMinor :: IO Int
botanVersionMinor :: IO Int
botanVersionMinor = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int) -> IO Word32 -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Word32
botan_version_minor

-- | Returns the patch version of the library
botanVersionPatch :: IO Int
botanVersionPatch :: IO Int
botanVersionPatch = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int) -> IO Word32 -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Word32
botan_version_patch

-- | Returns the date this version was released as an integer YYYYMMDD, or 0 if
-- an unreleased version
botanVersionDatestamp :: IO Int
botanVersionDatestamp :: IO Int
botanVersionDatestamp = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int) -> IO Word32 -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Word32
botan_version_datestamp