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

module GI.Soup.Objects.Cache
    ( 

-- * Exported types
    Cache(..)                               ,
    IsCache                                 ,
    toCache                                 ,
    noCache                                 ,


 -- * Methods
-- ** clear #method:clear#
    CacheClearMethodInfo                    ,
    cacheClear                              ,


-- ** dump #method:dump#
    CacheDumpMethodInfo                     ,
    cacheDump                               ,


-- ** flush #method:flush#
    CacheFlushMethodInfo                    ,
    cacheFlush                              ,


-- ** getMaxSize #method:getMaxSize#
    CacheGetMaxSizeMethodInfo               ,
    cacheGetMaxSize                         ,


-- ** load #method:load#
    CacheLoadMethodInfo                     ,
    cacheLoad                               ,


-- ** new #method:new#
    cacheNew                                ,


-- ** setMaxSize #method:setMaxSize#
    CacheSetMaxSizeMethodInfo               ,
    cacheSetMaxSize                         ,




 -- * Properties
-- ** cacheDir #attr:cacheDir#
    CacheCacheDirPropertyInfo               ,
    cacheCacheDir                           ,
    constructCacheCacheDir                  ,
    getCacheCacheDir                        ,


-- ** cacheType #attr:cacheType#
    CacheCacheTypePropertyInfo              ,
    cacheCacheType                          ,
    constructCacheCacheType                 ,
    getCacheCacheType                       ,




    ) 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.Soup.Enums as Soup.Enums
import {-# SOURCE #-} qualified GI.Soup.Interfaces.SessionFeature as Soup.SessionFeature

newtype Cache = Cache (ManagedPtr Cache)
foreign import ccall "soup_cache_get_type"
    c_soup_cache_get_type :: IO GType

instance GObject Cache where
    gobjectType _ = c_soup_cache_get_type
    

class GObject o => IsCache o
#if MIN_VERSION_base(4,9,0)
instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError Cache a) =>
    IsCache a
#endif
instance IsCache Cache
instance GObject.Object.IsObject Cache
instance Soup.SessionFeature.IsSessionFeature Cache

toCache :: IsCache o => o -> IO Cache
toCache = unsafeCastTo Cache

noCache :: Maybe Cache
noCache = Nothing

type family ResolveCacheMethod (t :: Symbol) (o :: *) :: * where
    ResolveCacheMethod "addFeature" o = Soup.SessionFeature.SessionFeatureAddFeatureMethodInfo
    ResolveCacheMethod "attach" o = Soup.SessionFeature.SessionFeatureAttachMethodInfo
    ResolveCacheMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo
    ResolveCacheMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo
    ResolveCacheMethod "clear" o = CacheClearMethodInfo
    ResolveCacheMethod "detach" o = Soup.SessionFeature.SessionFeatureDetachMethodInfo
    ResolveCacheMethod "dump" o = CacheDumpMethodInfo
    ResolveCacheMethod "flush" o = CacheFlushMethodInfo
    ResolveCacheMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo
    ResolveCacheMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo
    ResolveCacheMethod "hasFeature" o = Soup.SessionFeature.SessionFeatureHasFeatureMethodInfo
    ResolveCacheMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo
    ResolveCacheMethod "load" o = CacheLoadMethodInfo
    ResolveCacheMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo
    ResolveCacheMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo
    ResolveCacheMethod "ref" o = GObject.Object.ObjectRefMethodInfo
    ResolveCacheMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo
    ResolveCacheMethod "removeFeature" o = Soup.SessionFeature.SessionFeatureRemoveFeatureMethodInfo
    ResolveCacheMethod "replaceData" o = GObject.Object.ObjectReplaceDataMethodInfo
    ResolveCacheMethod "replaceQdata" o = GObject.Object.ObjectReplaceQdataMethodInfo
    ResolveCacheMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo
    ResolveCacheMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo
    ResolveCacheMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo
    ResolveCacheMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo
    ResolveCacheMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo
    ResolveCacheMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo
    ResolveCacheMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo
    ResolveCacheMethod "getMaxSize" o = CacheGetMaxSizeMethodInfo
    ResolveCacheMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo
    ResolveCacheMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo
    ResolveCacheMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo
    ResolveCacheMethod "setMaxSize" o = CacheSetMaxSizeMethodInfo
    ResolveCacheMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo
    ResolveCacheMethod l o = O.MethodResolutionFailed l o

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

#if MIN_VERSION_base(4,9,0)
instance (info ~ ResolveCacheMethod t Cache, O.MethodInfo info Cache p) => O.IsLabel t (Cache -> p) where
    fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#endif

-- VVV Prop "cache-dir"
   -- Type: TBasicType TUTF8
   -- Flags: [PropertyReadable,PropertyWritable,PropertyConstructOnly]
   -- Nullable: (Nothing,Nothing)

getCacheCacheDir :: (MonadIO m, IsCache o) => o -> m (Maybe T.Text)
getCacheCacheDir obj = liftIO $ getObjectPropertyString obj "cache-dir"

constructCacheCacheDir :: (IsCache o) => T.Text -> IO (GValueConstruct o)
constructCacheCacheDir val = constructObjectPropertyString "cache-dir" (Just val)

data CacheCacheDirPropertyInfo
instance AttrInfo CacheCacheDirPropertyInfo where
    type AttrAllowedOps CacheCacheDirPropertyInfo = '[ 'AttrConstruct, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint CacheCacheDirPropertyInfo = (~) T.Text
    type AttrBaseTypeConstraint CacheCacheDirPropertyInfo = IsCache
    type AttrGetType CacheCacheDirPropertyInfo = (Maybe T.Text)
    type AttrLabel CacheCacheDirPropertyInfo = "cache-dir"
    type AttrOrigin CacheCacheDirPropertyInfo = Cache
    attrGet _ = getCacheCacheDir
    attrSet _ = undefined
    attrConstruct _ = constructCacheCacheDir
    attrClear _ = undefined

-- VVV Prop "cache-type"
   -- Type: TInterface (Name {namespace = "Soup", name = "CacheType"})
   -- Flags: [PropertyReadable,PropertyWritable,PropertyConstructOnly]
   -- Nullable: (Nothing,Nothing)

getCacheCacheType :: (MonadIO m, IsCache o) => o -> m Soup.Enums.CacheType
getCacheCacheType obj = liftIO $ getObjectPropertyEnum obj "cache-type"

constructCacheCacheType :: (IsCache o) => Soup.Enums.CacheType -> IO (GValueConstruct o)
constructCacheCacheType val = constructObjectPropertyEnum "cache-type" val

data CacheCacheTypePropertyInfo
instance AttrInfo CacheCacheTypePropertyInfo where
    type AttrAllowedOps CacheCacheTypePropertyInfo = '[ 'AttrConstruct, 'AttrGet]
    type AttrSetTypeConstraint CacheCacheTypePropertyInfo = (~) Soup.Enums.CacheType
    type AttrBaseTypeConstraint CacheCacheTypePropertyInfo = IsCache
    type AttrGetType CacheCacheTypePropertyInfo = Soup.Enums.CacheType
    type AttrLabel CacheCacheTypePropertyInfo = "cache-type"
    type AttrOrigin CacheCacheTypePropertyInfo = Cache
    attrGet _ = getCacheCacheType
    attrSet _ = undefined
    attrConstruct _ = constructCacheCacheType
    attrClear _ = undefined

instance O.HasAttributeList Cache
type instance O.AttributeList Cache = CacheAttributeList
type CacheAttributeList = ('[ '("cacheDir", CacheCacheDirPropertyInfo), '("cacheType", CacheCacheTypePropertyInfo)] :: [(Symbol, *)])

cacheCacheDir :: AttrLabelProxy "cacheDir"
cacheCacheDir = AttrLabelProxy

cacheCacheType :: AttrLabelProxy "cacheType"
cacheCacheType = AttrLabelProxy

type instance O.SignalList Cache = CacheSignalList
type CacheSignalList = ('[ '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)])

-- method Cache::new
-- method type : Constructor
-- Args : [Arg {argCName = "cache_dir", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the directory to store the cached data, or %NULL to use the default one", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "cache_type", argType = TInterface (Name {namespace = "Soup", name = "CacheType"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #SoupCacheType of the cache", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Soup", name = "Cache"}))
-- throws : False
-- Skip return : False

foreign import ccall "soup_cache_new" soup_cache_new :: 
    CString ->                              -- cache_dir : TBasicType TUTF8
    CUInt ->                                -- cache_type : TInterface (Name {namespace = "Soup", name = "CacheType"})
    IO (Ptr Cache)

{- |
Creates a new 'GI.Soup.Objects.Cache.Cache'.

@since 2.34
-}
cacheNew ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    T.Text
    {- ^ /@cacheDir@/: the directory to store the cached data, or 'Nothing' to use the default one -}
    -> Soup.Enums.CacheType
    {- ^ /@cacheType@/: the 'GI.Soup.Enums.CacheType' of the cache -}
    -> m Cache
    {- ^ __Returns:__ a new 'GI.Soup.Objects.Cache.Cache' -}
cacheNew cacheDir cacheType = liftIO $ do
    cacheDir' <- textToCString cacheDir
    let cacheType' = (fromIntegral . fromEnum) cacheType
    result <- soup_cache_new cacheDir' cacheType'
    checkUnexpectedReturnNULL "cacheNew" result
    result' <- (wrapObject Cache) result
    freeMem cacheDir'
    return result'

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

foreign import ccall "soup_cache_clear" soup_cache_clear :: 
    Ptr Cache ->                            -- cache : TInterface (Name {namespace = "Soup", name = "Cache"})
    IO ()

{- |
Will remove all entries in the /@cache@/ plus all the cache files.

@since 2.34
-}
cacheClear ::
    (B.CallStack.HasCallStack, MonadIO m, IsCache a) =>
    a
    {- ^ /@cache@/: a 'GI.Soup.Objects.Cache.Cache' -}
    -> m ()
cacheClear cache = liftIO $ do
    cache' <- unsafeManagedPtrCastPtr cache
    soup_cache_clear cache'
    touchManagedPtr cache
    return ()

data CacheClearMethodInfo
instance (signature ~ (m ()), MonadIO m, IsCache a) => O.MethodInfo CacheClearMethodInfo a signature where
    overloadedMethod _ = cacheClear

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

foreign import ccall "soup_cache_dump" soup_cache_dump :: 
    Ptr Cache ->                            -- cache : TInterface (Name {namespace = "Soup", name = "Cache"})
    IO ()

{- |
Synchronously writes the cache index out to disk. Contrast with
'GI.Soup.Objects.Cache.cacheFlush', which writes pending cache
\<emphasis>entries\<\/emphasis> to disk.

You must call this before exiting if you want your cache data to
persist between sessions.

@since 2.34.
-}
cacheDump ::
    (B.CallStack.HasCallStack, MonadIO m, IsCache a) =>
    a
    {- ^ /@cache@/: a 'GI.Soup.Objects.Cache.Cache' -}
    -> m ()
cacheDump cache = liftIO $ do
    cache' <- unsafeManagedPtrCastPtr cache
    soup_cache_dump cache'
    touchManagedPtr cache
    return ()

data CacheDumpMethodInfo
instance (signature ~ (m ()), MonadIO m, IsCache a) => O.MethodInfo CacheDumpMethodInfo a signature where
    overloadedMethod _ = cacheDump

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

foreign import ccall "soup_cache_flush" soup_cache_flush :: 
    Ptr Cache ->                            -- cache : TInterface (Name {namespace = "Soup", name = "Cache"})
    IO ()

{- |
This function will force all pending writes in the /@cache@/ to be
committed to disk. For doing so it will iterate the 'GI.GLib.Structs.MainContext.MainContext'
associated with /@cache@/\'s session as long as needed.

Contrast with 'GI.Soup.Objects.Cache.cacheDump', which writes out the cache index
file.

@since 2.34
-}
cacheFlush ::
    (B.CallStack.HasCallStack, MonadIO m, IsCache a) =>
    a
    {- ^ /@cache@/: a 'GI.Soup.Objects.Cache.Cache' -}
    -> m ()
cacheFlush cache = liftIO $ do
    cache' <- unsafeManagedPtrCastPtr cache
    soup_cache_flush cache'
    touchManagedPtr cache
    return ()

data CacheFlushMethodInfo
instance (signature ~ (m ()), MonadIO m, IsCache a) => O.MethodInfo CacheFlushMethodInfo a signature where
    overloadedMethod _ = cacheFlush

-- method Cache::get_max_size
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "cache", argType = TInterface (Name {namespace = "Soup", name = "Cache"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #SoupCache", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TUInt)
-- throws : False
-- Skip return : False

foreign import ccall "soup_cache_get_max_size" soup_cache_get_max_size :: 
    Ptr Cache ->                            -- cache : TInterface (Name {namespace = "Soup", name = "Cache"})
    IO Word32

{- |
Gets the maximum size of the cache.

@since 2.34
-}
cacheGetMaxSize ::
    (B.CallStack.HasCallStack, MonadIO m, IsCache a) =>
    a
    {- ^ /@cache@/: a 'GI.Soup.Objects.Cache.Cache' -}
    -> m Word32
    {- ^ __Returns:__ the maximum size of the cache, in bytes. -}
cacheGetMaxSize cache = liftIO $ do
    cache' <- unsafeManagedPtrCastPtr cache
    result <- soup_cache_get_max_size cache'
    touchManagedPtr cache
    return result

data CacheGetMaxSizeMethodInfo
instance (signature ~ (m Word32), MonadIO m, IsCache a) => O.MethodInfo CacheGetMaxSizeMethodInfo a signature where
    overloadedMethod _ = cacheGetMaxSize

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

foreign import ccall "soup_cache_load" soup_cache_load :: 
    Ptr Cache ->                            -- cache : TInterface (Name {namespace = "Soup", name = "Cache"})
    IO ()

{- |
Loads the contents of /@cache@/\'s index into memory.

@since 2.34
-}
cacheLoad ::
    (B.CallStack.HasCallStack, MonadIO m, IsCache a) =>
    a
    {- ^ /@cache@/: a 'GI.Soup.Objects.Cache.Cache' -}
    -> m ()
cacheLoad cache = liftIO $ do
    cache' <- unsafeManagedPtrCastPtr cache
    soup_cache_load cache'
    touchManagedPtr cache
    return ()

data CacheLoadMethodInfo
instance (signature ~ (m ()), MonadIO m, IsCache a) => O.MethodInfo CacheLoadMethodInfo a signature where
    overloadedMethod _ = cacheLoad

-- method Cache::set_max_size
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "cache", argType = TInterface (Name {namespace = "Soup", name = "Cache"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #SoupCache", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "max_size", argType = TBasicType TUInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the maximum size of the cache, in bytes", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "soup_cache_set_max_size" soup_cache_set_max_size :: 
    Ptr Cache ->                            -- cache : TInterface (Name {namespace = "Soup", name = "Cache"})
    Word32 ->                               -- max_size : TBasicType TUInt
    IO ()

{- |
Sets the maximum size of the cache.

@since 2.34
-}
cacheSetMaxSize ::
    (B.CallStack.HasCallStack, MonadIO m, IsCache a) =>
    a
    {- ^ /@cache@/: a 'GI.Soup.Objects.Cache.Cache' -}
    -> Word32
    {- ^ /@maxSize@/: the maximum size of the cache, in bytes -}
    -> m ()
cacheSetMaxSize cache maxSize = liftIO $ do
    cache' <- unsafeManagedPtrCastPtr cache
    soup_cache_set_max_size cache' maxSize
    touchManagedPtr cache
    return ()

data CacheSetMaxSizeMethodInfo
instance (signature ~ (Word32 -> m ()), MonadIO m, IsCache a) => O.MethodInfo CacheSetMaxSizeMethodInfo a signature where
    overloadedMethod _ = cacheSetMaxSize