{- |
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 git remote.
-}

module GI.Ggit.Objects.Remote
    ( 

-- * Exported types
    Remote(..)                              ,
    IsRemote                                ,
    toRemote                                ,
    noRemote                                ,


 -- * Methods
-- ** connect #method:connect#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    RemoteConnectMethodInfo                 ,
#endif
    remoteConnect                           ,


-- ** disconnect #method:disconnect#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    RemoteDisconnectMethodInfo              ,
#endif
    remoteDisconnect                        ,


-- ** download #method:download#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    RemoteDownloadMethodInfo                ,
#endif
    remoteDownload                          ,


-- ** getConnected #method:getConnected#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    RemoteGetConnectedMethodInfo            ,
#endif
    remoteGetConnected                      ,


-- ** getFetchSpecs #method:getFetchSpecs#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    RemoteGetFetchSpecsMethodInfo           ,
#endif
    remoteGetFetchSpecs                     ,


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


-- ** getOwner #method:getOwner#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    RemoteGetOwnerMethodInfo                ,
#endif
    remoteGetOwner                          ,


-- ** getPushSpecs #method:getPushSpecs#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    RemoteGetPushSpecsMethodInfo            ,
#endif
    remoteGetPushSpecs                      ,


-- ** getUrl #method:getUrl#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    RemoteGetUrlMethodInfo                  ,
#endif
    remoteGetUrl                            ,


-- ** list #method:list#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    RemoteListMethodInfo                    ,
#endif
    remoteList                              ,


-- ** new #method:new#
    remoteNew                               ,


-- ** newAnonymous #method:newAnonymous#
    remoteNewAnonymous                      ,


-- ** updateTips #method:updateTips#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    RemoteUpdateTipsMethodInfo              ,
#endif
    remoteUpdateTips                        ,




    ) 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.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.Objects.ProxyOptions as Ggit.ProxyOptions
import {-# SOURCE #-} qualified GI.Ggit.Objects.RemoteCallbacks as Ggit.RemoteCallbacks
import {-# SOURCE #-} qualified GI.Ggit.Objects.Repository as Ggit.Repository
import {-# SOURCE #-} qualified GI.Ggit.Structs.FetchOptions as Ggit.FetchOptions
import {-# SOURCE #-} qualified GI.Ggit.Structs.RemoteHead as Ggit.RemoteHead

newtype Remote = Remote (ManagedPtr Remote)
foreign import ccall "ggit_remote_get_type"
    c_ggit_remote_get_type :: IO GType

instance GObject Remote where
    gobjectType _ = c_ggit_remote_get_type
    

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

toRemote :: (MonadIO m, IsRemote o) => o -> m Remote
toRemote = liftIO . unsafeCastTo Remote

noRemote :: Maybe Remote
noRemote = Nothing

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
type family ResolveRemoteMethod (t :: Symbol) (o :: *) :: * where
    ResolveRemoteMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo
    ResolveRemoteMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo
    ResolveRemoteMethod "connect" o = RemoteConnectMethodInfo
    ResolveRemoteMethod "disconnect" o = RemoteDisconnectMethodInfo
    ResolveRemoteMethod "download" o = RemoteDownloadMethodInfo
    ResolveRemoteMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo
    ResolveRemoteMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo
    ResolveRemoteMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo
    ResolveRemoteMethod "list" o = RemoteListMethodInfo
    ResolveRemoteMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo
    ResolveRemoteMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo
    ResolveRemoteMethod "ref" o = GObject.Object.ObjectRefMethodInfo
    ResolveRemoteMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo
    ResolveRemoteMethod "replaceData" o = GObject.Object.ObjectReplaceDataMethodInfo
    ResolveRemoteMethod "replaceQdata" o = GObject.Object.ObjectReplaceQdataMethodInfo
    ResolveRemoteMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo
    ResolveRemoteMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo
    ResolveRemoteMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo
    ResolveRemoteMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo
    ResolveRemoteMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo
    ResolveRemoteMethod "updateTips" o = RemoteUpdateTipsMethodInfo
    ResolveRemoteMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo
    ResolveRemoteMethod "getConnected" o = RemoteGetConnectedMethodInfo
    ResolveRemoteMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo
    ResolveRemoteMethod "getFetchSpecs" o = RemoteGetFetchSpecsMethodInfo
    ResolveRemoteMethod "getName" o = RemoteGetNameMethodInfo
    ResolveRemoteMethod "getOwner" o = RemoteGetOwnerMethodInfo
    ResolveRemoteMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo
    ResolveRemoteMethod "getPushSpecs" o = RemoteGetPushSpecsMethodInfo
    ResolveRemoteMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo
    ResolveRemoteMethod "getUrl" o = RemoteGetUrlMethodInfo
    ResolveRemoteMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo
    ResolveRemoteMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo
    ResolveRemoteMethod l o = O.MethodResolutionFailed l o

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

#if MIN_VERSION_base(4,9,0)
instance (info ~ ResolveRemoteMethod t Remote, O.MethodInfo info Remote p) => O.IsLabel t (Remote -> 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 Remote
type instance O.AttributeList Remote = RemoteAttributeList
type RemoteAttributeList = ('[ '("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 Remote = RemoteSignalList
type RemoteSignalList = ('[ '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)])

#endif

-- method Remote::new
-- method type : Constructor
-- Args : [Arg {argCName = "repository", argType = TInterface (Name {namespace = "Ggit", name = "Repository"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitRepository.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "name", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the remote's name.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "url", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the remote repository's URL.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Ggit", name = "Remote"}))
-- throws : True
-- Skip return : False

foreign import ccall "ggit_remote_new" ggit_remote_new :: 
    Ptr Ggit.Repository.Repository ->       -- repository : TInterface (Name {namespace = "Ggit", name = "Repository"})
    CString ->                              -- name : TBasicType TUTF8
    CString ->                              -- url : TBasicType TUTF8
    Ptr (Ptr GError) ->                     -- error
    IO (Ptr Remote)

{- |
Creates a remote with the default refspecs in memory. You can use
this when you have a URL instead of a remote\'s name.
-}
remoteNew ::
    (B.CallStack.HasCallStack, MonadIO m, Ggit.Repository.IsRepository a) =>
    a
    {- ^ /@repository@/: a 'GI.Ggit.Objects.Repository.Repository'. -}
    -> T.Text
    {- ^ /@name@/: the remote\'s name. -}
    -> T.Text
    {- ^ /@url@/: the remote repository\'s URL. -}
    -> m Remote
    {- ^ __Returns:__ a newly allocated 'GI.Ggit.Objects.Remote.Remote'. /(Can throw 'Data.GI.Base.GError.GError')/ -}
remoteNew repository name url = liftIO $ do
    repository' <- unsafeManagedPtrCastPtr repository
    name' <- textToCString name
    url' <- textToCString url
    onException (do
        result <- propagateGError $ ggit_remote_new repository' name' url'
        checkUnexpectedReturnNULL "remoteNew" result
        result' <- (wrapObject Remote) result
        touchManagedPtr repository
        freeMem name'
        freeMem url'
        return result'
     ) (do
        freeMem name'
        freeMem url'
     )

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

-- method Remote::new_anonymous
-- method type : Constructor
-- Args : [Arg {argCName = "repository", argType = TInterface (Name {namespace = "Ggit", name = "Repository"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitRepository.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "url", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the remote repository's URL.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Ggit", name = "Remote"}))
-- throws : True
-- Skip return : False

foreign import ccall "ggit_remote_new_anonymous" ggit_remote_new_anonymous :: 
    Ptr Ggit.Repository.Repository ->       -- repository : TInterface (Name {namespace = "Ggit", name = "Repository"})
    CString ->                              -- url : TBasicType TUTF8
    Ptr (Ptr GError) ->                     -- error
    IO (Ptr Remote)

{- |
Creates a remote with the specified refspec in memory. You can use
this when you have a URL instead of a remote\'s name.
-}
remoteNewAnonymous ::
    (B.CallStack.HasCallStack, MonadIO m, Ggit.Repository.IsRepository a) =>
    a
    {- ^ /@repository@/: a 'GI.Ggit.Objects.Repository.Repository'. -}
    -> T.Text
    {- ^ /@url@/: the remote repository\'s URL. -}
    -> m Remote
    {- ^ __Returns:__ a newly allocated 'GI.Ggit.Objects.Remote.Remote'. /(Can throw 'Data.GI.Base.GError.GError')/ -}
remoteNewAnonymous repository url = liftIO $ do
    repository' <- unsafeManagedPtrCastPtr repository
    url' <- textToCString url
    onException (do
        result <- propagateGError $ ggit_remote_new_anonymous repository' url'
        checkUnexpectedReturnNULL "remoteNewAnonymous" result
        result' <- (wrapObject Remote) result
        touchManagedPtr repository
        freeMem url'
        return result'
     ) (do
        freeMem url'
     )

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

-- method Remote::connect
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "remote", argType = TInterface (Name {namespace = "Ggit", name = "Remote"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitRemote.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "direction", argType = TInterface (Name {namespace = "Ggit", name = "Direction"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "whether you want to receive or send data.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "callbacks", argType = TInterface (Name {namespace = "Ggit", name = "RemoteCallbacks"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the callbacks to use for this connection.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "proxy_options", argType = TInterface (Name {namespace = "Ggit", name = "ProxyOptions"}), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "the proxy options.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "custom_headers", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "extra HTTP headers to use in this connection.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : True
-- Skip return : False

foreign import ccall "ggit_remote_connect" ggit_remote_connect :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    CUInt ->                                -- direction : TInterface (Name {namespace = "Ggit", name = "Direction"})
    Ptr Ggit.RemoteCallbacks.RemoteCallbacks -> -- callbacks : TInterface (Name {namespace = "Ggit", name = "RemoteCallbacks"})
    Ptr Ggit.ProxyOptions.ProxyOptions ->   -- proxy_options : TInterface (Name {namespace = "Ggit", name = "ProxyOptions"})
    CString ->                              -- custom_headers : TBasicType TUTF8
    Ptr (Ptr GError) ->                     -- error
    IO ()

{- |
Opens a connection to a remote.
The transport is selected based on the URL. The direction argument
is due to a limitation of the git protocol (over TCP or SSH) which
starts up a specific binary which can only do the one or the other.
-}
remoteConnect ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a, Ggit.RemoteCallbacks.IsRemoteCallbacks b, Ggit.ProxyOptions.IsProxyOptions c) =>
    a
    {- ^ /@remote@/: a 'GI.Ggit.Objects.Remote.Remote'. -}
    -> Ggit.Enums.Direction
    {- ^ /@direction@/: whether you want to receive or send data. -}
    -> b
    {- ^ /@callbacks@/: the callbacks to use for this connection. -}
    -> Maybe (c)
    {- ^ /@proxyOptions@/: the proxy options. -}
    -> Maybe (T.Text)
    {- ^ /@customHeaders@/: extra HTTP headers to use in this connection. -}
    -> m ()
    {- ^ /(Can throw 'Data.GI.Base.GError.GError')/ -}
remoteConnect remote direction callbacks proxyOptions customHeaders = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    let direction' = (fromIntegral . fromEnum) direction
    callbacks' <- unsafeManagedPtrCastPtr callbacks
    maybeProxyOptions <- case proxyOptions of
        Nothing -> return nullPtr
        Just jProxyOptions -> do
            jProxyOptions' <- unsafeManagedPtrCastPtr jProxyOptions
            return jProxyOptions'
    maybeCustomHeaders <- case customHeaders of
        Nothing -> return nullPtr
        Just jCustomHeaders -> do
            jCustomHeaders' <- textToCString jCustomHeaders
            return jCustomHeaders'
    onException (do
        propagateGError $ ggit_remote_connect remote' direction' callbacks' maybeProxyOptions maybeCustomHeaders
        touchManagedPtr remote
        touchManagedPtr callbacks
        whenJust proxyOptions touchManagedPtr
        freeMem maybeCustomHeaders
        return ()
     ) (do
        freeMem maybeCustomHeaders
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data RemoteConnectMethodInfo
instance (signature ~ (Ggit.Enums.Direction -> b -> Maybe (c) -> Maybe (T.Text) -> m ()), MonadIO m, IsRemote a, Ggit.RemoteCallbacks.IsRemoteCallbacks b, Ggit.ProxyOptions.IsProxyOptions c) => O.MethodInfo RemoteConnectMethodInfo a signature where
    overloadedMethod _ = remoteConnect

#endif

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

foreign import ccall "ggit_remote_disconnect" ggit_remote_disconnect :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    IO ()

{- |
Closes the connection to the remote and frees the underlying
transport.
-}
remoteDisconnect ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a) =>
    a
    {- ^ /@remote@/: a 'GI.Ggit.Objects.Remote.Remote'. -}
    -> m ()
remoteDisconnect remote = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    ggit_remote_disconnect remote'
    touchManagedPtr remote
    return ()

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

#endif

-- method Remote::download
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "remote", argType = TInterface (Name {namespace = "Ggit", name = "Remote"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitRemote.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "specs", argType = TCArray True (-1) (-1) (TBasicType TUTF8), direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "the ref specs.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "fetch_options", argType = TInterface (Name {namespace = "Ggit", name = "FetchOptions"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitFetchOptions.", 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_remote_download" ggit_remote_download :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    Ptr CString ->                          -- specs : TCArray True (-1) (-1) (TBasicType TUTF8)
    Ptr Ggit.FetchOptions.FetchOptions ->   -- fetch_options : TInterface (Name {namespace = "Ggit", name = "FetchOptions"})
    Ptr (Ptr GError) ->                     -- error
    IO CInt

{- |
Connect to the remote if not yet connected, negotiate with the remote
about which objects are missing and download the resulting packfile and
its index.
-}
remoteDownload ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a) =>
    a
    {- ^ /@remote@/: a 'GI.Ggit.Objects.Remote.Remote'. -}
    -> Maybe ([T.Text])
    {- ^ /@specs@/: the ref specs. -}
    -> Ggit.FetchOptions.FetchOptions
    {- ^ /@fetchOptions@/: a 'GI.Ggit.Structs.FetchOptions.FetchOptions'. -}
    -> m ()
    {- ^ /(Can throw 'Data.GI.Base.GError.GError')/ -}
remoteDownload remote specs fetchOptions = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    maybeSpecs <- case specs of
        Nothing -> return nullPtr
        Just jSpecs -> do
            jSpecs' <- packZeroTerminatedUTF8CArray jSpecs
            return jSpecs'
    fetchOptions' <- unsafeManagedPtrGetPtr fetchOptions
    onException (do
        _ <- propagateGError $ ggit_remote_download remote' maybeSpecs fetchOptions'
        touchManagedPtr remote
        touchManagedPtr fetchOptions
        mapZeroTerminatedCArray freeMem maybeSpecs
        freeMem maybeSpecs
        return ()
     ) (do
        mapZeroTerminatedCArray freeMem maybeSpecs
        freeMem maybeSpecs
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data RemoteDownloadMethodInfo
instance (signature ~ (Maybe ([T.Text]) -> Ggit.FetchOptions.FetchOptions -> m ()), MonadIO m, IsRemote a) => O.MethodInfo RemoteDownloadMethodInfo a signature where
    overloadedMethod _ = remoteDownload

#endif

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

foreign import ccall "ggit_remote_get_connected" ggit_remote_get_connected :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    IO CInt

{- |
Check whether /@remote@/ is connected.
-}
remoteGetConnected ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a) =>
    a
    {- ^ /@remote@/: a 'GI.Ggit.Objects.Remote.Remote'. -}
    -> m Bool
    {- ^ __Returns:__ 'True' if it is connected. -}
remoteGetConnected remote = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    result <- ggit_remote_get_connected remote'
    let result' = (/= 0) result
    touchManagedPtr remote
    return result'

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data RemoteGetConnectedMethodInfo
instance (signature ~ (m Bool), MonadIO m, IsRemote a) => O.MethodInfo RemoteGetConnectedMethodInfo a signature where
    overloadedMethod _ = remoteGetConnected

#endif

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

foreign import ccall "ggit_remote_get_fetch_specs" ggit_remote_get_fetch_specs :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    Ptr (Ptr GError) ->                     -- error
    IO (Ptr CString)

{- |
Get the list of fetch refspecs for the given remote.
-}
remoteGetFetchSpecs ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a) =>
    a
    {- ^ /@remote@/: a 'GI.Ggit.Objects.Remote.Remote'. -}
    -> m (Maybe [T.Text])
    {- ^ __Returns:__ a list of fetch refspecs. /(Can throw 'Data.GI.Base.GError.GError')/ -}
remoteGetFetchSpecs remote = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    onException (do
        result <- propagateGError $ ggit_remote_get_fetch_specs remote'
        maybeResult <- convertIfNonNull result $ \result' -> do
            result'' <- unpackZeroTerminatedUTF8CArray result'
            mapZeroTerminatedCArray freeMem result'
            freeMem result'
            return result''
        touchManagedPtr remote
        return maybeResult
     ) (do
        return ()
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data RemoteGetFetchSpecsMethodInfo
instance (signature ~ (m (Maybe [T.Text])), MonadIO m, IsRemote a) => O.MethodInfo RemoteGetFetchSpecsMethodInfo a signature where
    overloadedMethod _ = remoteGetFetchSpecs

#endif

-- method Remote::get_name
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "remote", argType = TInterface (Name {namespace = "Ggit", name = "Remote"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitRemote.", 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 "ggit_remote_get_name" ggit_remote_get_name :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    IO CString

{- |
Gets the remote\'s name.
-}
remoteGetName ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a) =>
    a
    {- ^ /@remote@/: a 'GI.Ggit.Objects.Remote.Remote'. -}
    -> m T.Text
    {- ^ __Returns:__ the name of /@remote@/. -}
remoteGetName remote = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    result <- ggit_remote_get_name remote'
    checkUnexpectedReturnNULL "remoteGetName" result
    result' <- cstringToText result
    touchManagedPtr remote
    return result'

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

#endif

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

foreign import ccall "ggit_remote_get_owner" ggit_remote_get_owner :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    IO (Ptr Ggit.Repository.Repository)

{- |
Gets the repository where /@remote@/ resides.
-}
remoteGetOwner ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a) =>
    a
    {- ^ /@remote@/: a 'GI.Ggit.Objects.Remote.Remote'. -}
    -> m Ggit.Repository.Repository
    {- ^ __Returns:__ the repository where the remote resides. -}
remoteGetOwner remote = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    result <- ggit_remote_get_owner remote'
    checkUnexpectedReturnNULL "remoteGetOwner" result
    result' <- (wrapObject Ggit.Repository.Repository) result
    touchManagedPtr remote
    return result'

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data RemoteGetOwnerMethodInfo
instance (signature ~ (m Ggit.Repository.Repository), MonadIO m, IsRemote a) => O.MethodInfo RemoteGetOwnerMethodInfo a signature where
    overloadedMethod _ = remoteGetOwner

#endif

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

foreign import ccall "ggit_remote_get_push_specs" ggit_remote_get_push_specs :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    Ptr (Ptr GError) ->                     -- error
    IO (Ptr CString)

{- |
Get the list of push refspecs for the given remote.
-}
remoteGetPushSpecs ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a) =>
    a
    {- ^ /@remote@/: a 'GI.Ggit.Objects.Remote.Remote'. -}
    -> m (Maybe [T.Text])
    {- ^ __Returns:__ a list of push refspecs. /(Can throw 'Data.GI.Base.GError.GError')/ -}
remoteGetPushSpecs remote = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    onException (do
        result <- propagateGError $ ggit_remote_get_push_specs remote'
        maybeResult <- convertIfNonNull result $ \result' -> do
            result'' <- unpackZeroTerminatedUTF8CArray result'
            mapZeroTerminatedCArray freeMem result'
            freeMem result'
            return result''
        touchManagedPtr remote
        return maybeResult
     ) (do
        return ()
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data RemoteGetPushSpecsMethodInfo
instance (signature ~ (m (Maybe [T.Text])), MonadIO m, IsRemote a) => O.MethodInfo RemoteGetPushSpecsMethodInfo a signature where
    overloadedMethod _ = remoteGetPushSpecs

#endif

-- method Remote::get_url
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "remote", argType = TInterface (Name {namespace = "Ggit", name = "Remote"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "GgitRemote.", 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 "ggit_remote_get_url" ggit_remote_get_url :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    IO CString

{- |
Gets the remote\'s url.
-}
remoteGetUrl ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a) =>
    a
    {- ^ /@remote@/: GgitRemote. -}
    -> m T.Text
    {- ^ __Returns:__ the url of /@remote@/. -}
remoteGetUrl remote = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    result <- ggit_remote_get_url remote'
    checkUnexpectedReturnNULL "remoteGetUrl" result
    result' <- cstringToText result
    touchManagedPtr remote
    return result'

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

#endif

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

foreign import ccall "ggit_remote_list" ggit_remote_list :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    Ptr (Ptr GError) ->                     -- error
    IO (Ptr (Ptr Ggit.RemoteHead.RemoteHead))

{- |
Get a list of refs at the remote.
-}
remoteList ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a) =>
    a
    {- ^ /@remote@/: a 'GI.Ggit.Objects.Remote.Remote'. -}
    -> m [Ggit.RemoteHead.RemoteHead]
    {- ^ __Returns:__ the remote heads. /(Can throw 'Data.GI.Base.GError.GError')/ -}
remoteList remote = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    onException (do
        result <- propagateGError $ ggit_remote_list remote'
        checkUnexpectedReturnNULL "remoteList" result
        result' <- unpackZeroTerminatedPtrArray result
        result'' <- mapM (wrapBoxed Ggit.RemoteHead.RemoteHead) result'
        freeMem result
        touchManagedPtr remote
        return result''
     ) (do
        return ()
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data RemoteListMethodInfo
instance (signature ~ (m [Ggit.RemoteHead.RemoteHead]), MonadIO m, IsRemote a) => O.MethodInfo RemoteListMethodInfo a signature where
    overloadedMethod _ = remoteList

#endif

-- method Remote::update_tips
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "remote", argType = TInterface (Name {namespace = "Ggit", name = "Remote"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitRemote.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "callbacks", argType = TInterface (Name {namespace = "Ggit", name = "RemoteCallbacks"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GgitRemoteCallbacks.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "update_fetch_head", argType = TBasicType TBoolean, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "whether to write to FETCH_HEAD. %TRUE to behave like git.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "tags_type", argType = TInterface (Name {namespace = "Ggit", name = "RemoteDownloadTagsType"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "what the behaviour for downloading tags is for this fetch. This is\n            ignored for push. This must be the same value passed to\n            ggit_remote_download().", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "message", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "reflog_message The message to insert into the reflogs. If\n                        %NULL and fetching, the default is \"fetch <name>\",\n                        where <name> is the name of the remote (or its url,\n                        for in-memory remotes). This parameter is ignored when pushing.", 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_remote_update_tips" ggit_remote_update_tips :: 
    Ptr Remote ->                           -- remote : TInterface (Name {namespace = "Ggit", name = "Remote"})
    Ptr Ggit.RemoteCallbacks.RemoteCallbacks -> -- callbacks : TInterface (Name {namespace = "Ggit", name = "RemoteCallbacks"})
    CInt ->                                 -- update_fetch_head : TBasicType TBoolean
    CUInt ->                                -- tags_type : TInterface (Name {namespace = "Ggit", name = "RemoteDownloadTagsType"})
    CString ->                              -- message : TBasicType TUTF8
    Ptr (Ptr GError) ->                     -- error
    IO CInt

{- |
Update tips to the new state.
-}
remoteUpdateTips ::
    (B.CallStack.HasCallStack, MonadIO m, IsRemote a, Ggit.RemoteCallbacks.IsRemoteCallbacks b) =>
    a
    {- ^ /@remote@/: a 'GI.Ggit.Objects.Remote.Remote'. -}
    -> b
    {- ^ /@callbacks@/: a 'GI.Ggit.Objects.RemoteCallbacks.RemoteCallbacks'. -}
    -> Bool
    {- ^ /@updateFetchHead@/: whether to write to FETCH_HEAD. 'True' to behave like git. -}
    -> Ggit.Enums.RemoteDownloadTagsType
    {- ^ /@tagsType@/: what the behaviour for downloading tags is for this fetch. This is
            ignored for push. This must be the same value passed to
            'GI.Ggit.Objects.Remote.remoteDownload'. -}
    -> Maybe (T.Text)
    {- ^ /@message@/: reflog_message The message to insert into the reflogs. If
                        'Nothing' and fetching, the default is \"fetch \<name>\",
                        where \<name> is the name of the remote (or its url,
                        for in-memory remotes). This parameter is ignored when pushing. -}
    -> m ()
    {- ^ /(Can throw 'Data.GI.Base.GError.GError')/ -}
remoteUpdateTips remote callbacks updateFetchHead tagsType message = liftIO $ do
    remote' <- unsafeManagedPtrCastPtr remote
    callbacks' <- unsafeManagedPtrCastPtr callbacks
    let updateFetchHead' = (fromIntegral . fromEnum) updateFetchHead
    let tagsType' = (fromIntegral . fromEnum) tagsType
    maybeMessage <- case message of
        Nothing -> return nullPtr
        Just jMessage -> do
            jMessage' <- textToCString jMessage
            return jMessage'
    onException (do
        _ <- propagateGError $ ggit_remote_update_tips remote' callbacks' updateFetchHead' tagsType' maybeMessage
        touchManagedPtr remote
        touchManagedPtr callbacks
        freeMem maybeMessage
        return ()
     ) (do
        freeMem maybeMessage
     )

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data RemoteUpdateTipsMethodInfo
instance (signature ~ (b -> Bool -> Ggit.Enums.RemoteDownloadTagsType -> Maybe (T.Text) -> m ()), MonadIO m, IsRemote a, Ggit.RemoteCallbacks.IsRemoteCallbacks b) => O.MethodInfo RemoteUpdateTipsMethodInfo a signature where
    overloadedMethod _ = remoteUpdateTips

#endif