{- |
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.ContentSniffer
    ( 

-- * Exported types
    ContentSniffer(..)                      ,
    IsContentSniffer                        ,
    toContentSniffer                        ,
    noContentSniffer                        ,


 -- * Methods
-- ** getBufferSize #method:getBufferSize#
    ContentSnifferGetBufferSizeMethodInfo   ,
    contentSnifferGetBufferSize             ,


-- ** new #method:new#
    contentSnifferNew                       ,


-- ** sniff #method:sniff#
    ContentSnifferSniffMethodInfo           ,
    contentSnifferSniff                     ,




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

newtype ContentSniffer = ContentSniffer (ManagedPtr ContentSniffer)
foreign import ccall "soup_content_sniffer_get_type"
    c_soup_content_sniffer_get_type :: IO GType

instance GObject ContentSniffer where
    gobjectType _ = c_soup_content_sniffer_get_type
    

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

toContentSniffer :: IsContentSniffer o => o -> IO ContentSniffer
toContentSniffer = unsafeCastTo ContentSniffer

noContentSniffer :: Maybe ContentSniffer
noContentSniffer = Nothing

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

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

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

instance O.HasAttributeList ContentSniffer
type instance O.AttributeList ContentSniffer = ContentSnifferAttributeList
type ContentSnifferAttributeList = ('[ ] :: [(Symbol, *)])

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

-- method ContentSniffer::new
-- method type : Constructor
-- Args : []
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Soup", name = "ContentSniffer"}))
-- throws : False
-- Skip return : False

foreign import ccall "soup_content_sniffer_new" soup_content_sniffer_new :: 
    IO (Ptr ContentSniffer)

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

@since 2.28
-}
contentSnifferNew ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    m ContentSniffer
    {- ^ __Returns:__ a new 'GI.Soup.Objects.ContentSniffer.ContentSniffer' -}
contentSnifferNew  = liftIO $ do
    result <- soup_content_sniffer_new
    checkUnexpectedReturnNULL "contentSnifferNew" result
    result' <- (wrapObject ContentSniffer) result
    return result'

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

foreign import ccall "soup_content_sniffer_get_buffer_size" soup_content_sniffer_get_buffer_size :: 
    Ptr ContentSniffer ->                   -- sniffer : TInterface (Name {namespace = "Soup", name = "ContentSniffer"})
    IO Word64

{- |
Gets the number of bytes /@sniffer@/ needs in order to properly sniff
a buffer.

@since 2.28
-}
contentSnifferGetBufferSize ::
    (B.CallStack.HasCallStack, MonadIO m, IsContentSniffer a) =>
    a
    {- ^ /@sniffer@/: a 'GI.Soup.Objects.ContentSniffer.ContentSniffer' -}
    -> m Word64
    {- ^ __Returns:__ the number of bytes to sniff -}
contentSnifferGetBufferSize sniffer = liftIO $ do
    sniffer' <- unsafeManagedPtrCastPtr sniffer
    result <- soup_content_sniffer_get_buffer_size sniffer'
    touchManagedPtr sniffer
    return result

data ContentSnifferGetBufferSizeMethodInfo
instance (signature ~ (m Word64), MonadIO m, IsContentSniffer a) => O.MethodInfo ContentSnifferGetBufferSizeMethodInfo a signature where
    overloadedMethod _ = contentSnifferGetBufferSize

-- method ContentSniffer::sniff
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "sniffer", argType = TInterface (Name {namespace = "Soup", name = "ContentSniffer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #SoupContentSniffer", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "msg", argType = TInterface (Name {namespace = "Soup", name = "Message"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the message to sniff", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "buffer", argType = TInterface (Name {namespace = "Soup", name = "Buffer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a buffer containing the start of @msg's response body", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "params", argType = TGHash (TBasicType TUTF8) (TBasicType TUTF8), direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "return\n  location for Content-Type parameters (eg, \"charset\"), or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
-- Lengths : []
-- returnType : Just (TBasicType TUTF8)
-- throws : False
-- Skip return : False

foreign import ccall "soup_content_sniffer_sniff" soup_content_sniffer_sniff :: 
    Ptr ContentSniffer ->                   -- sniffer : TInterface (Name {namespace = "Soup", name = "ContentSniffer"})
    Ptr Soup.Message.Message ->             -- msg : TInterface (Name {namespace = "Soup", name = "Message"})
    Ptr Soup.Buffer.Buffer ->               -- buffer : TInterface (Name {namespace = "Soup", name = "Buffer"})
    Ptr (Ptr (GHashTable CString CString)) -> -- params : TGHash (TBasicType TUTF8) (TBasicType TUTF8)
    IO CString

{- |
Sniffs /@buffer@/ to determine its Content-Type. The result may also
be influenced by the Content-Type declared in /@msg@/\'s response
headers.

@since 2.28
-}
contentSnifferSniff ::
    (B.CallStack.HasCallStack, MonadIO m, IsContentSniffer a, Soup.Message.IsMessage b) =>
    a
    {- ^ /@sniffer@/: a 'GI.Soup.Objects.ContentSniffer.ContentSniffer' -}
    -> b
    {- ^ /@msg@/: the message to sniff -}
    -> Soup.Buffer.Buffer
    {- ^ /@buffer@/: a buffer containing the start of /@msg@/\'s response body -}
    -> m (T.Text,(Map.Map T.Text T.Text))
    {- ^ __Returns:__ the sniffed Content-Type of /@buffer@/; this will never be 'Nothing',
  but may be \"application\/octet-stream\". -}
contentSnifferSniff sniffer msg buffer = liftIO $ do
    sniffer' <- unsafeManagedPtrCastPtr sniffer
    msg' <- unsafeManagedPtrCastPtr msg
    buffer' <- unsafeManagedPtrGetPtr buffer
    params <- allocMem :: IO (Ptr (Ptr (GHashTable CString CString)))
    result <- soup_content_sniffer_sniff sniffer' msg' buffer' params
    checkUnexpectedReturnNULL "contentSnifferSniff" result
    result' <- cstringToText result
    freeMem result
    params' <- peek params
    params'' <- unpackGHashTable params'
    let params''' = mapFirst cstringUnpackPtr params''
    params'''' <- mapFirstA cstringToText params'''
    let params''''' = mapSecond cstringUnpackPtr params''''
    params'''''' <- mapSecondA cstringToText params'''''
    let params''''''' = Map.fromList params''''''
    unrefGHashTable params'
    touchManagedPtr sniffer
    touchManagedPtr msg
    touchManagedPtr buffer
    freeMem params
    return (result', params''''''')

data ContentSnifferSniffMethodInfo
instance (signature ~ (b -> Soup.Buffer.Buffer -> m (T.Text,(Map.Map T.Text T.Text))), MonadIO m, IsContentSniffer a, Soup.Message.IsMessage b) => O.MethodInfo ContentSnifferSniffMethodInfo a signature where
    overloadedMethod _ = contentSnifferSniff