{- |
Copyright  : Will Thompson, Iñaki García Etxebarria and Jonas Platte
License    : LGPL-2.1
Maintainer : Iñaki García Etxebarria (inaki@blueleaf.cc)

A secret value, like a password or other binary secret.
-}

#define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \
       && !defined(__HADDOCK_VERSION__))

module GI.Secret.Structs.Value
    (

-- * Exported types
    Value(..)                               ,
    noValue                                 ,


 -- * Methods
-- ** get #method:get#

#if ENABLE_OVERLOADING
    ValueGetMethodInfo                      ,
#endif
    valueGet                                ,


-- ** getContentType #method:getContentType#

#if ENABLE_OVERLOADING
    ValueGetContentTypeMethodInfo           ,
#endif
    valueGetContentType                     ,


-- ** getText #method:getText#

#if ENABLE_OVERLOADING
    ValueGetTextMethodInfo                  ,
#endif
    valueGetText                            ,


-- ** new #method:new#

    valueNew                                ,


-- ** newFull #method:newFull#

    valueNewFull                            ,


-- ** ref #method:ref#

#if ENABLE_OVERLOADING
    ValueRefMethodInfo                      ,
#endif
    valueRef                                ,


-- ** unref #method:unref#

#if ENABLE_OVERLOADING
    ValueUnrefMethodInfo                    ,
#endif
    valueUnref                              ,




    ) where

import Data.GI.Base.ShortPrelude
import qualified Data.GI.Base.ShortPrelude as SP
import qualified Data.GI.Base.Overloading as O
import qualified Prelude as P

import qualified Data.GI.Base.Attributes as GI.Attributes
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GClosure as B.GClosure
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GVariant as B.GVariant
import qualified Data.GI.Base.GValue as B.GValue
import qualified Data.GI.Base.GParamSpec as B.GParamSpec
import qualified Data.GI.Base.CallStack as B.CallStack
import qualified Data.GI.Base.Properties as B.Properties
import qualified Data.Text as T
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
import qualified Foreign.Ptr as FP
import qualified GHC.OverloadedLabels as OL

import qualified GI.GLib.Callbacks as GLib.Callbacks

-- | Memory-managed wrapper type.
newtype Value = Value (ManagedPtr Value)
foreign import ccall "secret_value_get_type" c_secret_value_get_type ::
    IO GType

instance BoxedObject Value where
    boxedType _ = c_secret_value_get_type

-- | A convenience alias for `Nothing` :: `Maybe` `Value`.
noValue :: Maybe Value
noValue = Nothing


#if ENABLE_OVERLOADING
instance O.HasAttributeList Value
type instance O.AttributeList Value = ValueAttributeList
type ValueAttributeList = ('[ ] :: [(Symbol, *)])
#endif

-- method Value::new
-- method type : Constructor
-- Args : [Arg {argCName = "secret", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the secret data", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "length", argType = TBasicType TInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the length of the data", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "content_type", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the content type of the data", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Secret", name = "Value"}))
-- throws : False
-- Skip return : False

foreign import ccall "secret_value_new" secret_value_new ::
    CString ->                              -- secret : TBasicType TUTF8
    Int64 ->                                -- length : TBasicType TInt64
    CString ->                              -- content_type : TBasicType TUTF8
    IO (Ptr Value)

{- |
Create a 'GI.Secret.Structs.Value.Value' for the secret data passed in. The secret data is
copied into non-pageable \'secure\' memory.

If the length is less than zero, then /@secret@/ is assumed to be
null-terminated.
-}
valueNew ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    T.Text
    {- ^ /@secret@/: the secret data -}
    -> Int64
    {- ^ /@length@/: the length of the data -}
    -> T.Text
    {- ^ /@contentType@/: the content type of the data -}
    -> m Value
    {- ^ __Returns:__ the new 'GI.Secret.Structs.Value.Value' -}
valueNew secret length_ contentType = liftIO $ do
    secret' <- textToCString secret
    contentType' <- textToCString contentType
    result <- secret_value_new secret' length_ contentType'
    checkUnexpectedReturnNULL "valueNew" result
    result' <- (wrapBoxed Value) result
    freeMem secret'
    freeMem contentType'
    return result'

#if ENABLE_OVERLOADING
#endif

-- method Value::new_full
-- method type : Constructor
-- Args : [Arg {argCName = "secret", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the secret data", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "length", argType = TBasicType TInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the length of the data", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "content_type", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the content type of the data", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "destroy", argType = TInterface (Name {namespace = "GLib", name = "DestroyNotify"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "function to call to free the secret data", sinceVersion = Nothing}, argScope = ScopeTypeAsync, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Secret", name = "Value"}))
-- throws : False
-- Skip return : False

foreign import ccall "secret_value_new_full" secret_value_new_full ::
    CString ->                              -- secret : TBasicType TUTF8
    Int64 ->                                -- length : TBasicType TInt64
    CString ->                              -- content_type : TBasicType TUTF8
    FunPtr GLib.Callbacks.C_DestroyNotify -> -- destroy : TInterface (Name {namespace = "GLib", name = "DestroyNotify"})
    IO (Ptr Value)

{- |
Create a 'GI.Secret.Structs.Value.Value' for the secret data passed in. The secret data is
not copied, and will later be freed with the /@destroy@/ function.

If the length is less than zero, then /@secret@/ is assumed to be
null-terminated.
-}
valueNewFull ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    T.Text
    {- ^ /@secret@/: the secret data -}
    -> Int64
    {- ^ /@length@/: the length of the data -}
    -> T.Text
    {- ^ /@contentType@/: the content type of the data -}
    -> GLib.Callbacks.DestroyNotify
    {- ^ /@destroy@/: function to call to free the secret data -}
    -> m Value
    {- ^ __Returns:__ the new 'GI.Secret.Structs.Value.Value' -}
valueNewFull secret length_ contentType destroy = liftIO $ do
    secret' <- textToCString secret
    contentType' <- textToCString contentType
    ptrdestroy <- callocMem :: IO (Ptr (FunPtr GLib.Callbacks.C_DestroyNotify))
    destroy' <- GLib.Callbacks.mk_DestroyNotify (GLib.Callbacks.wrap_DestroyNotify (Just ptrdestroy) destroy)
    poke ptrdestroy destroy'
    result <- secret_value_new_full secret' length_ contentType' destroy'
    checkUnexpectedReturnNULL "valueNewFull" result
    result' <- (wrapBoxed Value) result
    freeMem secret'
    freeMem contentType'
    return result'

#if ENABLE_OVERLOADING
#endif

-- method Value::get
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "value", argType = TInterface (Name {namespace = "Secret", name = "Value"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the value", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "length", argType = TBasicType TUInt64, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the length of the secret", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
-- Lengths : [Arg {argCName = "length", argType = TBasicType TUInt64, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the length of the secret", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
-- returnType : Just (TCArray False (-1) 1 (TBasicType TUInt8))
-- throws : False
-- Skip return : False

foreign import ccall "secret_value_get" secret_value_get ::
    Ptr Value ->                            -- value : TInterface (Name {namespace = "Secret", name = "Value"})
    Ptr Word64 ->                           -- length : TBasicType TUInt64
    IO (Ptr Word8)

{- |
Get the secret data in the 'GI.Secret.Structs.Value.Value'. The value is not necessarily
null-terminated unless it was created with 'GI.Secret.Structs.Value.valueNew' or a
null-terminated string was passed to 'GI.Secret.Structs.Value.valueNewFull'.
-}
valueGet ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Value
    {- ^ /@value@/: the value -}
    -> m ByteString
    {- ^ __Returns:__ the secret data -}
valueGet value = liftIO $ do
    value' <- unsafeManagedPtrGetPtr value
    length_ <- allocMem :: IO (Ptr Word64)
    result <- secret_value_get value' length_
    length_' <- peek length_
    checkUnexpectedReturnNULL "valueGet" result
    result' <- (unpackByteStringWithLength length_') result
    touchManagedPtr value
    freeMem length_
    return result'

#if ENABLE_OVERLOADING
data ValueGetMethodInfo
instance (signature ~ (m ByteString), MonadIO m) => O.MethodInfo ValueGetMethodInfo Value signature where
    overloadedMethod _ = valueGet

#endif

-- method Value::get_content_type
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "value", argType = TInterface (Name {namespace = "Secret", name = "Value"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the value", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TUTF8)
-- throws : False
-- Skip return : False

foreign import ccall "secret_value_get_content_type" secret_value_get_content_type ::
    Ptr Value ->                            -- value : TInterface (Name {namespace = "Secret", name = "Value"})
    IO CString

{- |
Get the content type of the secret value, such as
\<literal>text\/plain\<\/literal>.
-}
valueGetContentType ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Value
    {- ^ /@value@/: the value -}
    -> m T.Text
    {- ^ __Returns:__ the content type -}
valueGetContentType value = liftIO $ do
    value' <- unsafeManagedPtrGetPtr value
    result <- secret_value_get_content_type value'
    checkUnexpectedReturnNULL "valueGetContentType" result
    result' <- cstringToText result
    touchManagedPtr value
    return result'

#if ENABLE_OVERLOADING
data ValueGetContentTypeMethodInfo
instance (signature ~ (m T.Text), MonadIO m) => O.MethodInfo ValueGetContentTypeMethodInfo Value signature where
    overloadedMethod _ = valueGetContentType

#endif

-- method Value::get_text
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "value", argType = TInterface (Name {namespace = "Secret", name = "Value"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the value", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TUTF8)
-- throws : False
-- Skip return : False

foreign import ccall "secret_value_get_text" secret_value_get_text ::
    Ptr Value ->                            -- value : TInterface (Name {namespace = "Secret", name = "Value"})
    IO CString

{- |
Get the secret data in the 'GI.Secret.Structs.Value.Value' if it contains a textual
value. The content type must be \<literal>text\/plain\<\/literal>.
-}
valueGetText ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Value
    {- ^ /@value@/: the value -}
    -> m (Maybe T.Text)
    {- ^ __Returns:__ the content type -}
valueGetText value = liftIO $ do
    value' <- unsafeManagedPtrGetPtr value
    result <- secret_value_get_text value'
    maybeResult <- convertIfNonNull result $ \result' -> do
        result'' <- cstringToText result'
        return result''
    touchManagedPtr value
    return maybeResult

#if ENABLE_OVERLOADING
data ValueGetTextMethodInfo
instance (signature ~ (m (Maybe T.Text)), MonadIO m) => O.MethodInfo ValueGetTextMethodInfo Value signature where
    overloadedMethod _ = valueGetText

#endif

-- method Value::ref
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "value", argType = TInterface (Name {namespace = "Secret", name = "Value"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "value to reference", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Secret", name = "Value"}))
-- throws : False
-- Skip return : False

foreign import ccall "secret_value_ref" secret_value_ref ::
    Ptr Value ->                            -- value : TInterface (Name {namespace = "Secret", name = "Value"})
    IO (Ptr Value)

{- |
Add another reference to the 'GI.Secret.Structs.Value.Value'. For each reference
'GI.Secret.Structs.Value.valueUnref' should be called to unreference the value.
-}
valueRef ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Value
    {- ^ /@value@/: value to reference -}
    -> m Value
    {- ^ __Returns:__ the value -}
valueRef value = liftIO $ do
    value' <- unsafeManagedPtrGetPtr value
    result <- secret_value_ref value'
    checkUnexpectedReturnNULL "valueRef" result
    result' <- (wrapBoxed Value) result
    touchManagedPtr value
    return result'

#if ENABLE_OVERLOADING
data ValueRefMethodInfo
instance (signature ~ (m Value), MonadIO m) => O.MethodInfo ValueRefMethodInfo Value signature where
    overloadedMethod _ = valueRef

#endif

-- method Value::unref
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "value", argType = TInterface (Name {namespace = "Secret", name = "Value"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "value to unreference", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "secret_value_unref" secret_value_unref ::
    Ptr Value ->                            -- value : TInterface (Name {namespace = "Secret", name = "Value"})
    IO ()

{- |
Unreference a 'GI.Secret.Structs.Value.Value'. When the last reference is gone, then
the value will be freed.
-}
valueUnref ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Value
    {- ^ /@value@/: value to unreference -}
    -> m ()
valueUnref value = liftIO $ do
    value' <- unsafeManagedPtrGetPtr value
    secret_value_unref value'
    touchManagedPtr value
    return ()

#if ENABLE_OVERLOADING
data ValueUnrefMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo ValueUnrefMethodInfo Value signature where
    overloadedMethod _ = valueUnref

#endif

#if ENABLE_OVERLOADING
type family ResolveValueMethod (t :: Symbol) (o :: *) :: * where
    ResolveValueMethod "get" o = ValueGetMethodInfo
    ResolveValueMethod "ref" o = ValueRefMethodInfo
    ResolveValueMethod "unref" o = ValueUnrefMethodInfo
    ResolveValueMethod "getContentType" o = ValueGetContentTypeMethodInfo
    ResolveValueMethod "getText" o = ValueGetTextMethodInfo
    ResolveValueMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveValueMethod t Value, O.MethodInfo info Value p) => OL.IsLabel t (Value -> p) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#else
    fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#endif

#endif