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

Represents a tree object.
-}

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

module GI.Ggit.Objects.TreeBuilder
    (

-- * Exported types
    TreeBuilder(..)                         ,
    IsTreeBuilder                           ,
    toTreeBuilder                           ,
    noTreeBuilder                           ,


 -- * Methods
-- ** clear #method:clear#

#if ENABLE_OVERLOADING
    TreeBuilderClearMethodInfo              ,
#endif
    treeBuilderClear                        ,


-- ** getEntry #method:getEntry#

#if ENABLE_OVERLOADING
    TreeBuilderGetEntryMethodInfo           ,
#endif
    treeBuilderGetEntry                     ,


-- ** insert #method:insert#

#if ENABLE_OVERLOADING
    TreeBuilderInsertMethodInfo             ,
#endif
    treeBuilderInsert                       ,


-- ** remove #method:remove#

#if ENABLE_OVERLOADING
    TreeBuilderRemoveMethodInfo             ,
#endif
    treeBuilderRemove                       ,


-- ** write #method:write#

#if ENABLE_OVERLOADING
    TreeBuilderWriteMethodInfo              ,
#endif
    treeBuilderWrite                        ,




    ) 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.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.Text as T
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
import qualified Foreign.Ptr as FP

import qualified GI.GObject.Objects.Object as GObject.Object
import {-# SOURCE #-} qualified GI.Ggit.Enums as Ggit.Enums
import {-# SOURCE #-} qualified GI.Ggit.Objects.Native as Ggit.Native
import {-# SOURCE #-} qualified GI.Ggit.Objects.ObjectFactoryBase as Ggit.ObjectFactoryBase
import {-# SOURCE #-} qualified GI.Ggit.Structs.OId as Ggit.OId
import {-# SOURCE #-} qualified GI.Ggit.Structs.TreeEntry as Ggit.TreeEntry

-- | Memory-managed wrapper type.
newtype TreeBuilder = TreeBuilder (ManagedPtr TreeBuilder)
foreign import ccall "ggit_tree_builder_get_type"
    c_ggit_tree_builder_get_type :: IO GType

instance GObject TreeBuilder where
    gobjectType _ = c_ggit_tree_builder_get_type


-- | Type class for types which can be safely cast to `TreeBuilder`, for instance with `toTreeBuilder`.
class GObject o => IsTreeBuilder o
#if MIN_VERSION_base(4,9,0)
instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError TreeBuilder a) =>
    IsTreeBuilder a
#endif
instance IsTreeBuilder TreeBuilder
instance Ggit.Native.IsNative TreeBuilder
instance Ggit.ObjectFactoryBase.IsObjectFactoryBase TreeBuilder
instance GObject.Object.IsObject TreeBuilder

-- | Cast to `TreeBuilder`, for types for which this is known to be safe. For general casts, use `Data.GI.Base.ManagedPtr.castTo`.
toTreeBuilder :: (MonadIO m, IsTreeBuilder o) => o -> m TreeBuilder
toTreeBuilder = liftIO . unsafeCastTo TreeBuilder

-- | A convenience alias for `Nothing` :: `Maybe` `TreeBuilder`.
noTreeBuilder :: Maybe TreeBuilder
noTreeBuilder = Nothing

#if ENABLE_OVERLOADING
type family ResolveTreeBuilderMethod (t :: Symbol) (o :: *) :: * where
    ResolveTreeBuilderMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo
    ResolveTreeBuilderMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo
    ResolveTreeBuilderMethod "clear" o = TreeBuilderClearMethodInfo
    ResolveTreeBuilderMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo
    ResolveTreeBuilderMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo
    ResolveTreeBuilderMethod "getv" o = GObject.Object.ObjectGetvMethodInfo
    ResolveTreeBuilderMethod "insert" o = TreeBuilderInsertMethodInfo
    ResolveTreeBuilderMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo
    ResolveTreeBuilderMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo
    ResolveTreeBuilderMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo
    ResolveTreeBuilderMethod "ref" o = GObject.Object.ObjectRefMethodInfo
    ResolveTreeBuilderMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo
    ResolveTreeBuilderMethod "remove" o = TreeBuilderRemoveMethodInfo
    ResolveTreeBuilderMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo
    ResolveTreeBuilderMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo
    ResolveTreeBuilderMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo
    ResolveTreeBuilderMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo
    ResolveTreeBuilderMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo
    ResolveTreeBuilderMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo
    ResolveTreeBuilderMethod "write" o = TreeBuilderWriteMethodInfo
    ResolveTreeBuilderMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo
    ResolveTreeBuilderMethod "getEntry" o = TreeBuilderGetEntryMethodInfo
    ResolveTreeBuilderMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo
    ResolveTreeBuilderMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo
    ResolveTreeBuilderMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo
    ResolveTreeBuilderMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo
    ResolveTreeBuilderMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveTreeBuilderMethod t TreeBuilder, O.MethodInfo info TreeBuilder p) => O.IsLabelProxy t (TreeBuilder -> p) where
    fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)

#if MIN_VERSION_base(4,9,0)
instance (info ~ ResolveTreeBuilderMethod t TreeBuilder, O.MethodInfo info TreeBuilder p) => O.IsLabel t (TreeBuilder -> 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

#endif

#if ENABLE_OVERLOADING
instance O.HasAttributeList TreeBuilder
type instance O.AttributeList TreeBuilder = TreeBuilderAttributeList
type TreeBuilderAttributeList = ('[ '("native", Ggit.Native.NativeNativePropertyInfo)] :: [(Symbol, *)])
#endif

#if ENABLE_OVERLOADING
#endif

#if ENABLE_OVERLOADING
type instance O.SignalList TreeBuilder = TreeBuilderSignalList
type TreeBuilderSignalList = ('[ '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)])

#endif

-- method TreeBuilder::clear
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "Ggit", name = "TreeBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitTreeBuilder.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "ggit_tree_builder_clear" ggit_tree_builder_clear ::
    Ptr TreeBuilder ->                      -- builder : TInterface (Name {namespace = "Ggit", name = "TreeBuilder"})
    IO ()

{- |
Clear all entries in the tree builder.
-}
treeBuilderClear ::
    (B.CallStack.HasCallStack, MonadIO m, IsTreeBuilder a) =>
    a
    {- ^ /@builder@/: a 'GI.Ggit.Objects.TreeBuilder.TreeBuilder'. -}
    -> m ()
treeBuilderClear builder = liftIO $ do
    builder' <- unsafeManagedPtrCastPtr builder
    ggit_tree_builder_clear builder'
    touchManagedPtr builder
    return ()

#if ENABLE_OVERLOADING
data TreeBuilderClearMethodInfo
instance (signature ~ (m ()), MonadIO m, IsTreeBuilder a) => O.MethodInfo TreeBuilderClearMethodInfo a signature where
    overloadedMethod _ = treeBuilderClear

#endif

-- method TreeBuilder::get_entry
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "Ggit", name = "TreeBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitTreeBuilder.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "path", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the path to remove.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Ggit", name = "TreeEntry"}))
-- throws : False
-- Skip return : False

foreign import ccall "ggit_tree_builder_get_entry" ggit_tree_builder_get_entry ::
    Ptr TreeBuilder ->                      -- builder : TInterface (Name {namespace = "Ggit", name = "TreeBuilder"})
    CString ->                              -- path : TBasicType TUTF8
    IO (Ptr Ggit.TreeEntry.TreeEntry)

{- |
Get an entry by path.
-}
treeBuilderGetEntry ::
    (B.CallStack.HasCallStack, MonadIO m, IsTreeBuilder a) =>
    a
    {- ^ /@builder@/: a 'GI.Ggit.Objects.TreeBuilder.TreeBuilder'. -}
    -> T.Text
    {- ^ /@path@/: the path to remove. -}
    -> m (Maybe Ggit.TreeEntry.TreeEntry)
    {- ^ __Returns:__ the @/GGitTreeEntry/@ or 'Nothing' if no such entry exists. -}
treeBuilderGetEntry builder path = liftIO $ do
    builder' <- unsafeManagedPtrCastPtr builder
    path' <- textToCString path
    result <- ggit_tree_builder_get_entry builder' path'
    maybeResult <- convertIfNonNull result $ \result' -> do
        result'' <- (wrapBoxed Ggit.TreeEntry.TreeEntry) result'
        return result''
    touchManagedPtr builder
    freeMem path'
    return maybeResult

#if ENABLE_OVERLOADING
data TreeBuilderGetEntryMethodInfo
instance (signature ~ (T.Text -> m (Maybe Ggit.TreeEntry.TreeEntry)), MonadIO m, IsTreeBuilder a) => O.MethodInfo TreeBuilderGetEntryMethodInfo a signature where
    overloadedMethod _ = treeBuilderGetEntry

#endif

-- method TreeBuilder::insert
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "Ggit", name = "TreeBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitTreeBuilder.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "filename", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the file name.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "oid", argType = TInterface (Name {namespace = "Ggit", name = "OId"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GgitOId of the file blob to insert.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "file_mode", argType = TInterface (Name {namespace = "Ggit", name = "FileMode"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitFileMode.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Ggit", name = "TreeEntry"}))
-- throws : True
-- Skip return : False

foreign import ccall "ggit_tree_builder_insert" ggit_tree_builder_insert ::
    Ptr TreeBuilder ->                      -- builder : TInterface (Name {namespace = "Ggit", name = "TreeBuilder"})
    CString ->                              -- filename : TBasicType TUTF8
    Ptr Ggit.OId.OId ->                     -- oid : TInterface (Name {namespace = "Ggit", name = "OId"})
    CUInt ->                                -- file_mode : TInterface (Name {namespace = "Ggit", name = "FileMode"})
    Ptr (Ptr GError) ->                     -- error
    IO (Ptr Ggit.TreeEntry.TreeEntry)

{- |
Insert a file with a given blob in the tree builder. If the tree builder
already contains an entry for the given file, then this entry will be
overwritten.

Note that the returned 'GI.Ggit.Structs.TreeEntry.TreeEntry' is bound to the lifetime of the tree
builder and cannot be used after the tree builder has been freed.
-}
treeBuilderInsert ::
    (B.CallStack.HasCallStack, MonadIO m, IsTreeBuilder a) =>
    a
    {- ^ /@builder@/: a 'GI.Ggit.Objects.TreeBuilder.TreeBuilder'. -}
    -> T.Text
    {- ^ /@filename@/: the file name. -}
    -> Ggit.OId.OId
    {- ^ /@oid@/: the 'GI.Ggit.Structs.OId.OId' of the file blob to insert. -}
    -> Ggit.Enums.FileMode
    {- ^ /@fileMode@/: a 'GI.Ggit.Enums.FileMode'. -}
    -> m (Maybe Ggit.TreeEntry.TreeEntry)
    {- ^ __Returns:__ a 'GI.Ggit.Structs.TreeEntry.TreeEntry' or 'Nothing'. /(Can throw 'Data.GI.Base.GError.GError')/ -}
treeBuilderInsert builder filename oid fileMode = liftIO $ do
    builder' <- unsafeManagedPtrCastPtr builder
    filename' <- textToCString filename
    oid' <- unsafeManagedPtrGetPtr oid
    let fileMode' = (fromIntegral . fromEnum) fileMode
    onException (do
        result <- propagateGError $ ggit_tree_builder_insert builder' filename' oid' fileMode'
        maybeResult <- convertIfNonNull result $ \result' -> do
            result'' <- (wrapBoxed Ggit.TreeEntry.TreeEntry) result'
            return result''
        touchManagedPtr builder
        touchManagedPtr oid
        freeMem filename'
        return maybeResult
     ) (do
        freeMem filename'
     )

#if ENABLE_OVERLOADING
data TreeBuilderInsertMethodInfo
instance (signature ~ (T.Text -> Ggit.OId.OId -> Ggit.Enums.FileMode -> m (Maybe Ggit.TreeEntry.TreeEntry)), MonadIO m, IsTreeBuilder a) => O.MethodInfo TreeBuilderInsertMethodInfo a signature where
    overloadedMethod _ = treeBuilderInsert

#endif

-- method TreeBuilder::remove
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "Ggit", name = "TreeBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitTreeBuilder.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "path", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the path to remove.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : True
-- Skip return : False

foreign import ccall "ggit_tree_builder_remove" ggit_tree_builder_remove ::
    Ptr TreeBuilder ->                      -- builder : TInterface (Name {namespace = "Ggit", name = "TreeBuilder"})
    CString ->                              -- path : TBasicType TUTF8
    Ptr (Ptr GError) ->                     -- error
    IO ()

{- |
Remove an entry from the builder by path.
-}
treeBuilderRemove ::
    (B.CallStack.HasCallStack, MonadIO m, IsTreeBuilder a) =>
    a
    {- ^ /@builder@/: a 'GI.Ggit.Objects.TreeBuilder.TreeBuilder'. -}
    -> T.Text
    {- ^ /@path@/: the path to remove. -}
    -> m ()
    {- ^ /(Can throw 'Data.GI.Base.GError.GError')/ -}
treeBuilderRemove builder path = liftIO $ do
    builder' <- unsafeManagedPtrCastPtr builder
    path' <- textToCString path
    onException (do
        propagateGError $ ggit_tree_builder_remove builder' path'
        touchManagedPtr builder
        freeMem path'
        return ()
     ) (do
        freeMem path'
     )

#if ENABLE_OVERLOADING
data TreeBuilderRemoveMethodInfo
instance (signature ~ (T.Text -> m ()), MonadIO m, IsTreeBuilder a) => O.MethodInfo TreeBuilderRemoveMethodInfo a signature where
    overloadedMethod _ = treeBuilderRemove

#endif

-- method TreeBuilder::write
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "Ggit", name = "TreeBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitTreeBuilder.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Ggit", name = "OId"}))
-- throws : True
-- Skip return : False

foreign import ccall "ggit_tree_builder_write" ggit_tree_builder_write ::
    Ptr TreeBuilder ->                      -- builder : TInterface (Name {namespace = "Ggit", name = "TreeBuilder"})
    Ptr (Ptr GError) ->                     -- error
    IO (Ptr Ggit.OId.OId)

{- |
Write the contents of the tree builder as a tree object.
-}
treeBuilderWrite ::
    (B.CallStack.HasCallStack, MonadIO m, IsTreeBuilder a) =>
    a
    {- ^ /@builder@/: a 'GI.Ggit.Objects.TreeBuilder.TreeBuilder'. -}
    -> m (Maybe Ggit.OId.OId)
    {- ^ __Returns:__ the 'GI.Ggit.Structs.OId.OId' of the created tree object or 'Nothing'. /(Can throw 'Data.GI.Base.GError.GError')/ -}
treeBuilderWrite builder = liftIO $ do
    builder' <- unsafeManagedPtrCastPtr builder
    onException (do
        result <- propagateGError $ ggit_tree_builder_write builder'
        maybeResult <- convertIfNonNull result $ \result' -> do
            result'' <- (wrapBoxed Ggit.OId.OId) result'
            return result''
        touchManagedPtr builder
        return maybeResult
     ) (do
        return ()
     )

#if ENABLE_OVERLOADING
data TreeBuilderWriteMethodInfo
instance (signature ~ (m (Maybe Ggit.OId.OId)), MonadIO m, IsTreeBuilder a) => O.MethodInfo TreeBuilderWriteMethodInfo a signature where
    overloadedMethod _ = treeBuilderWrite

#endif