module Text.XML.HXT.Arrow.XmlState.RunIOStateArrow
where
import Control.Arrow                            
import Control.Arrow.ArrowList
import Control.Arrow.IOStateListArrow
import Data.Map                                 ( empty )
import Text.XML.HXT.DOM.Interface
import Text.XML.HXT.Arrow.XmlArrow
import Text.XML.HXT.Arrow.XmlState.ErrorHandling
import Text.XML.HXT.Arrow.XmlState.TraceHandling
import Text.XML.HXT.Arrow.XmlState.TypeDefs
runX            :: IOSArrow XmlTree c -> IO [c]
runX            = runXIOState (initialState ())
runXIOState     :: XIOState s -> IOStateArrow s XmlTree c -> IO [c]
runXIOState s0 f
    = do
      (_finalState, res) <- runIOSLA (emptyRoot >>> f) s0 undefined
      return res
    where
    emptyRoot    = root [] []
initialState    :: us -> XIOState us
initialState s  = XIOState { xioSysState       = initialSysState
                           , xioUserState      = s
                           }
initialSysState                 :: XIOSysState
initialSysState                 = XIOSys
                                  { xioSysWriter         = initialSysWriter
                                  , xioSysEnv            = initialSysEnv
                                  }
initialSysWriter                :: XIOSysWriter
initialSysWriter                = XIOwrt
                                  { xioErrorStatus       = c_ok
                                  , xioErrorMsgList      = []
                                  , xioExpatErrors       = none
                                  , xioRelaxNoOfErrors   = 0
                                  , xioRelaxDefineId     = 0
                                  , xioRelaxAttrList     = []
                                  }
initialSysEnv                   :: XIOSysEnv
initialSysEnv                   = XIOEnv
                                  { xioTraceLevel        = 0
                                  , xioTraceCmd          = traceOutputToStderr
                                  , xioErrorMsgHandler   = errorOutputToStderr
                                  , xioErrorMsgCollect   = False
                                  , xioBaseURI           = ""
                                  , xioDefaultBaseURI    = ""
                                  , xioAttrList          = []
                                  , xioInputConfig       = initialInputConfig
                                  , xioParseConfig       = initialParseConfig
                                  , xioOutputConfig      = initialOutputConfig
                                  , xioRelaxConfig       = initialRelaxConfig
                                  , xioXmlSchemaConfig   = initialXmlSchemaConfig
                                  , xioCacheConfig       = initialCacheConfig
                                  }
initialInputConfig              :: XIOInputConfig
initialInputConfig              = XIOIcgf
                                  { xioStrictInput       = False
                                  , xioEncodingErrors    = True
                                  , xioInputEncoding     = ""
                                  , xioHttpHandler       = dummyHTTPHandler
                                  , xioInputOptions      = []
                                  , xioRedirect          = False
                                  , xioProxy             = ""
                                  }
initialParseConfig              :: XIOParseConfig
initialParseConfig              = XIOPcfg
                                  { xioMimeTypes                = defaultMimeTypeTable
                                  , xioMimeTypeHandlers         = empty
                                  , xioMimeTypeFile             = ""
                                  , xioAcceptedMimeTypes        = []
                                  , xioFileMimeType             = ""
                                  , xioWarnings                 = True
                                  , xioRemoveWS                 = False
                                  , xioParseByMimeType          = False
                                  , xioParseHTML                = False
                                  , xioLowerCaseNames           = False
                                  , xioTagSoup                  = False
                                  , xioPreserveComment          = False
                                  , xioValidate                 = True
                                  , xioSubstDTDEntities         = True
                                  , xioSubstHTMLEntities        = False
                                  , xioCheckNamespaces          = False
                                  , xioCanonicalize             = True
                                  , xioIgnoreNoneXmlContents    = False
                                  , xioTagSoupParser            = dummyTagSoupParser
                                  , xioExpat                    = False
                                  , xioExpatParser              = dummyExpatParser
                                  }
initialOutputConfig             :: XIOOutputConfig
initialOutputConfig             = XIOOcfg
                                  { xioIndent                   = False
                                  , xioOutputEncoding           = ""
                                  , xioOutputFmt                = XMLoutput
                                  , xioXmlPi                    = True
                                  , xioNoEmptyElemFor           = []
                                  , xioAddDefaultDTD            = False
                                  , xioTextMode                 = False
                                  , xioShowTree                 = False
                                  , xioShowHaskell              = False
                                  }
initialRelaxConfig              :: XIORelaxConfig
initialRelaxConfig              = XIORxc
                                  { xioRelaxValidate            = False
                                  , xioRelaxSchema              = ""
                                  , xioRelaxCheckRestr          = True
                                  , xioRelaxValidateExtRef      = True
                                  , xioRelaxValidateInclude     = True
                                  , xioRelaxCollectErrors       = True
                                  , xioRelaxValidator           = dummyRelaxValidator
                                  }
initialXmlSchemaConfig          :: XIOXmlSchemaConfig
initialXmlSchemaConfig          = XIOScc
                                  { xioXmlSchemaValidate        = False
                                  , xioXmlSchemaSchema          = ""
                                  , xioXmlSchemaValidator       = dummyXmlSchemaValidator
                                  }
initialCacheConfig              :: XIOCacheConfig
initialCacheConfig              = XIOCch
                                   { xioBinaryCompression       = id
                                   , xioBinaryDeCompression     = id
                                   , xioWithCache               = False
                                   , xioCacheDir                = ""
                                   , xioDocumentAge             = 0
                                   , xioCache404Err             = False
                                   , xioCacheRead               = dummyCacheRead
                                   , xioStrictDeserialize       = False
                                   }
dummyHTTPHandler        :: IOSArrow XmlTree XmlTree
dummyHTTPHandler        = ( issueFatal $
                            unlines $
                            [ "HTTP handler not configured,"
                            , "please install package hxt-curl and use 'withCurl' config option"
                            , "or install package hxt-http and use 'withHTTP' config option"
                            ]
                          )
                          >>>
                          addAttr transferMessage "HTTP handler not configured"
                          >>>
                          addAttr transferStatus "999"
dummyTagSoupParser      :: IOSArrow b b
dummyTagSoupParser      =  issueFatal $
                           unlines $
                           [ "TagSoup parser not configured,"
                           , "please install package hxt-tagsoup"
                           , " and use 'withTagSoup' parser config option from this package"
                           ]
dummyExpatParser        :: IOSArrow b b
dummyExpatParser        =  issueFatal $
                           unlines $
                           [ "Expat parser not configured,"
                           , "please install package hxt-expat"
                           , " and use 'withExpat' parser config option from this package"
                           ]
dummyRelaxValidator     :: IOSArrow b b
dummyRelaxValidator     =  issueFatal $
                           unlines $
                           [ "RelaxNG validator not configured,"
                           , "please install package hxt-relaxng"
                           , " and use 'withRelaxNG' config option from this package"
                           ]
dummyXmlSchemaValidator :: IOSArrow b b
dummyXmlSchemaValidator =  issueFatal $
                           unlines $
                           [ "XML Schema validator not configured,"
                           , "please install package hxt-xmlschema"
                           , " and use 'withXmlSchema' config option from this package"
                           ]
dummyCacheRead          :: String -> IOSArrow b b
dummyCacheRead          = const $
                          issueFatal $
                          unlines $
                          [ "Document cache not configured,"
                          , "please install package hxt-cache and use 'withCache' config option"
                          ]
getConfigAttr           :: String -> SysConfigList -> String
getConfigAttr n c       = lookup1 n $ tl
    where
    s                   = (foldr (>>>) id c) initialSysState
    tl                  = getS theAttrList s
theSysConfigComp        :: Selector XIOSysState a -> Selector SysConfig a
theSysConfigComp sel    = S { getS = \     cf -> getS sel      (cf initialSysState)
                            , setS = \ val cf -> setS sel val . cf
                            }