{- |
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 branch object.
-}

module GI.Ggit.Objects.Branch
    ( 

-- * Exported types
    Branch(..)                              ,
    IsBranch                                ,
    toBranch                                ,
    noBranch                                ,


 -- * Methods
-- ** delete #method:delete#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    BranchDeleteMethodInfo                  ,
#endif
    branchDelete                            ,


-- ** getName #method:getName#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    BranchGetNameMethodInfo                 ,
#endif
    branchGetName                           ,


-- ** getUpstream #method:getUpstream#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    BranchGetUpstreamMethodInfo             ,
#endif
    branchGetUpstream                       ,


-- ** isHead #method:isHead#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    BranchIsHeadMethodInfo                  ,
#endif
    branchIsHead                            ,


-- ** move #method:move#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    BranchMoveMethodInfo                    ,
#endif
    branchMove                              ,




    ) 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.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.Flags as Ggit.Flags
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.Objects.Ref as Ggit.Ref

newtype Branch = Branch (ManagedPtr Branch)
foreign import ccall "ggit_branch_get_type"
    c_ggit_branch_get_type :: IO GType

instance GObject Branch where
    gobjectType _ = c_ggit_branch_get_type
    

class GObject o => IsBranch o
#if MIN_VERSION_base(4,9,0)
instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError Branch a) =>
    IsBranch a
#endif
instance IsBranch Branch
instance Ggit.Ref.IsRef Branch
instance Ggit.Native.IsNative Branch
instance Ggit.ObjectFactoryBase.IsObjectFactoryBase Branch
instance GObject.Object.IsObject Branch

toBranch :: (MonadIO m, IsBranch o) => o -> m Branch
toBranch = liftIO . unsafeCastTo Branch

noBranch :: Maybe Branch
noBranch = Nothing

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
type family ResolveBranchMethod (t :: Symbol) (o :: *) :: * where
    ResolveBranchMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo
    ResolveBranchMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo
    ResolveBranchMethod "delete" o = BranchDeleteMethodInfo
    ResolveBranchMethod "deleteLog" o = Ggit.Ref.RefDeleteLogMethodInfo
    ResolveBranchMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo
    ResolveBranchMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo
    ResolveBranchMethod "hasLog" o = Ggit.Ref.RefHasLogMethodInfo
    ResolveBranchMethod "isBranch" o = Ggit.Ref.RefIsBranchMethodInfo
    ResolveBranchMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo
    ResolveBranchMethod "isHead" o = BranchIsHeadMethodInfo
    ResolveBranchMethod "isNote" o = Ggit.Ref.RefIsNoteMethodInfo
    ResolveBranchMethod "isRemote" o = Ggit.Ref.RefIsRemoteMethodInfo
    ResolveBranchMethod "isTag" o = Ggit.Ref.RefIsTagMethodInfo
    ResolveBranchMethod "lookup" o = Ggit.Ref.RefLookupMethodInfo
    ResolveBranchMethod "move" o = BranchMoveMethodInfo
    ResolveBranchMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo
    ResolveBranchMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo
    ResolveBranchMethod "ref" o = GObject.Object.ObjectRefMethodInfo
    ResolveBranchMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo
    ResolveBranchMethod "rename" o = Ggit.Ref.RefRenameMethodInfo
    ResolveBranchMethod "replaceData" o = GObject.Object.ObjectReplaceDataMethodInfo
    ResolveBranchMethod "replaceQdata" o = GObject.Object.ObjectReplaceQdataMethodInfo
    ResolveBranchMethod "resolve" o = Ggit.Ref.RefResolveMethodInfo
    ResolveBranchMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo
    ResolveBranchMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo
    ResolveBranchMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo
    ResolveBranchMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo
    ResolveBranchMethod "toString" o = Ggit.Ref.RefToStringMethodInfo
    ResolveBranchMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo
    ResolveBranchMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo
    ResolveBranchMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo
    ResolveBranchMethod "getLog" o = Ggit.Ref.RefGetLogMethodInfo
    ResolveBranchMethod "getName" o = BranchGetNameMethodInfo
    ResolveBranchMethod "getOwner" o = Ggit.Ref.RefGetOwnerMethodInfo
    ResolveBranchMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo
    ResolveBranchMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo
    ResolveBranchMethod "getReferenceType" o = Ggit.Ref.RefGetReferenceTypeMethodInfo
    ResolveBranchMethod "getShorthand" o = Ggit.Ref.RefGetShorthandMethodInfo
    ResolveBranchMethod "getSymbolicTarget" o = Ggit.Ref.RefGetSymbolicTargetMethodInfo
    ResolveBranchMethod "getTarget" o = Ggit.Ref.RefGetTargetMethodInfo
    ResolveBranchMethod "getUpstream" o = BranchGetUpstreamMethodInfo
    ResolveBranchMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo
    ResolveBranchMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo
    ResolveBranchMethod "setSymbolicTarget" o = Ggit.Ref.RefSetSymbolicTargetMethodInfo
    ResolveBranchMethod "setTarget" o = Ggit.Ref.RefSetTargetMethodInfo
    ResolveBranchMethod l o = O.MethodResolutionFailed l o

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

#if MIN_VERSION_base(4,9,0)
instance (info ~ ResolveBranchMethod t Branch, O.MethodInfo info Branch p) => O.IsLabel t (Branch -> 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 defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
instance O.HasAttributeList Branch
type instance O.AttributeList Branch = BranchAttributeList
type BranchAttributeList = ('[ '("native", Ggit.Native.NativeNativePropertyInfo)] :: [(Symbol, *)])
#endif

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
#endif

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
type instance O.SignalList Branch = BranchSignalList
type BranchSignalList = ('[ '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)])

#endif

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

foreign import ccall "ggit_branch_delete" ggit_branch_delete :: 
    Ptr Branch ->                           -- branch : TInterface (Name {namespace = "Ggit", name = "Branch"})
    Ptr (Ptr GError) ->                     -- error
    IO ()

{- |
Deletes an existing branch reference.

If the branch is successfully deleted, this object is
not useful anymore and if should be freed with 'GI.GObject.Objects.Object.objectUnref'.
-}
branchDelete ::
    (B.CallStack.HasCallStack, MonadIO m, IsBranch a) =>
    a
    {- ^ /@branch@/: a 'GI.Ggit.Objects.Branch.Branch'. -}
    -> m ()
    {- ^ /(Can throw 'Data.GI.Base.GError.GError')/ -}
branchDelete branch = liftIO $ do
    branch' <- unsafeManagedPtrCastPtr branch
    onException (do
        propagateGError $ ggit_branch_delete branch'
        touchManagedPtr branch
        return ()
     ) (do
        return ()
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data BranchDeleteMethodInfo
instance (signature ~ (m ()), MonadIO m, IsBranch a) => O.MethodInfo BranchDeleteMethodInfo a signature where
    overloadedMethod _ = branchDelete

#endif

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

foreign import ccall "ggit_branch_get_name" ggit_branch_get_name :: 
    Ptr Branch ->                           -- branch : TInterface (Name {namespace = "Ggit", name = "Branch"})
    Ptr (Ptr GError) ->                     -- error
    IO CString

{- |
Gets the name of the given local or remote branch.
-}
branchGetName ::
    (B.CallStack.HasCallStack, MonadIO m, IsBranch a) =>
    a
    {- ^ /@branch@/: a 'GI.Ggit.Objects.Branch.Branch'. -}
    -> m T.Text
    {- ^ __Returns:__ the name of the given local or remote branch. /(Can throw 'Data.GI.Base.GError.GError')/ -}
branchGetName branch = liftIO $ do
    branch' <- unsafeManagedPtrCastPtr branch
    onException (do
        result <- propagateGError $ ggit_branch_get_name branch'
        checkUnexpectedReturnNULL "branchGetName" result
        result' <- cstringToText result
        touchManagedPtr branch
        return result'
     ) (do
        return ()
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data BranchGetNameMethodInfo
instance (signature ~ (m T.Text), MonadIO m, IsBranch a) => O.MethodInfo BranchGetNameMethodInfo a signature where
    overloadedMethod _ = branchGetName

#endif

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

foreign import ccall "ggit_branch_get_upstream" ggit_branch_get_upstream :: 
    Ptr Branch ->                           -- branch : TInterface (Name {namespace = "Ggit", name = "Branch"})
    Ptr (Ptr GError) ->                     -- error
    IO (Ptr Ggit.Ref.Ref)

{- |
Gets the reference supporting the remote tracking branch,
given a local branch reference.
-}
branchGetUpstream ::
    (B.CallStack.HasCallStack, MonadIO m, IsBranch a) =>
    a
    {- ^ /@branch@/: a 'GI.Ggit.Objects.Branch.Branch'. -}
    -> m (Maybe Ggit.Ref.Ref)
    {- ^ __Returns:__ the reference supporting the remote tracking branch. /(Can throw 'Data.GI.Base.GError.GError')/ -}
branchGetUpstream branch = liftIO $ do
    branch' <- unsafeManagedPtrCastPtr branch
    onException (do
        result <- propagateGError $ ggit_branch_get_upstream branch'
        maybeResult <- convertIfNonNull result $ \result' -> do
            result'' <- (wrapObject Ggit.Ref.Ref) result'
            return result''
        touchManagedPtr branch
        return maybeResult
     ) (do
        return ()
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data BranchGetUpstreamMethodInfo
instance (signature ~ (m (Maybe Ggit.Ref.Ref)), MonadIO m, IsBranch a) => O.MethodInfo BranchGetUpstreamMethodInfo a signature where
    overloadedMethod _ = branchGetUpstream

#endif

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

foreign import ccall "ggit_branch_is_head" ggit_branch_is_head :: 
    Ptr Branch ->                           -- branch : TInterface (Name {namespace = "Ggit", name = "Branch"})
    Ptr (Ptr GError) ->                     -- error
    IO CInt

{- |
Determines if the current local branch is pointed at by HEAD.
-}
branchIsHead ::
    (B.CallStack.HasCallStack, MonadIO m, IsBranch a) =>
    a
    {- ^ /@branch@/: a 'GI.Ggit.Objects.Branch.Branch'. -}
    -> m ()
    {- ^ /(Can throw 'Data.GI.Base.GError.GError')/ -}
branchIsHead branch = liftIO $ do
    branch' <- unsafeManagedPtrCastPtr branch
    onException (do
        _ <- propagateGError $ ggit_branch_is_head branch'
        touchManagedPtr branch
        return ()
     ) (do
        return ()
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data BranchIsHeadMethodInfo
instance (signature ~ (m ()), MonadIO m, IsBranch a) => O.MethodInfo BranchIsHeadMethodInfo a signature where
    overloadedMethod _ = branchIsHead

#endif

-- method Branch::move
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "branch", argType = TInterface (Name {namespace = "Ggit", name = "Branch"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitBranch.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "new_branch_name", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "target name of the branch once the move is performed; this name is validated for consistency.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "flags", argType = TInterface (Name {namespace = "Ggit", name = "CreateFlags"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitCreateFlags.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Ggit", name = "Branch"}))
-- throws : True
-- Skip return : False

foreign import ccall "ggit_branch_move" ggit_branch_move :: 
    Ptr Branch ->                           -- branch : TInterface (Name {namespace = "Ggit", name = "Branch"})
    CString ->                              -- new_branch_name : TBasicType TUTF8
    CUInt ->                                -- flags : TInterface (Name {namespace = "Ggit", name = "CreateFlags"})
    Ptr (Ptr GError) ->                     -- error
    IO (Ptr Branch)

{- |
Moves\/renames an existing branch reference.
-}
branchMove ::
    (B.CallStack.HasCallStack, MonadIO m, IsBranch a) =>
    a
    {- ^ /@branch@/: a 'GI.Ggit.Objects.Branch.Branch'. -}
    -> T.Text
    {- ^ /@newBranchName@/: target name of the branch once the move is performed; this name is validated for consistency. -}
    -> [Ggit.Flags.CreateFlags]
    {- ^ /@flags@/: a 'GI.Ggit.Flags.CreateFlags'. -}
    -> m Branch
    {- ^ __Returns:__ the new branch. /(Can throw 'Data.GI.Base.GError.GError')/ -}
branchMove branch newBranchName flags = liftIO $ do
    branch' <- unsafeManagedPtrCastPtr branch
    newBranchName' <- textToCString newBranchName
    let flags' = gflagsToWord flags
    onException (do
        result <- propagateGError $ ggit_branch_move branch' newBranchName' flags'
        checkUnexpectedReturnNULL "branchMove" result
        result' <- (wrapObject Branch) result
        touchManagedPtr branch
        freeMem newBranchName'
        return result'
     ) (do
        freeMem newBranchName'
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data BranchMoveMethodInfo
instance (signature ~ (T.Text -> [Ggit.Flags.CreateFlags] -> m Branch), MonadIO m, IsBranch a) => O.MethodInfo BranchMoveMethodInfo a signature where
    overloadedMethod _ = branchMove

#endif