definition module iTasks.Internal.TaskServer

from iTasks.Internal.IWorld import :: ConnectionId
from iTasks.Internal.SDS import :: SDSSource

from StdFile			import class FileSystem
from TCPIP				import class ChannelEnv, :: IPAddress, :: Timeout
from Internet.HTTP		import :: HTTPRequest, :: HTTPResponse
from System.FilePath    import :: FilePath
from TCPDef		          import :: SelectResult

from Data.Error               import :: MaybeError, :: MaybeErrorString
from Data.Map                 import :: Map
from iTasks.WF.Definition     import :: TaskId
from iTasks.Internal.IWorld	  import :: IWorld
from iTasks.Internal.Task     import :: ConnectionTask, :: TaskException
from iTasks.Internal.IWorld   import :: IWorld, :: IOStates, :: IOState
from iTasks.Internal.IWorld	  import :: IWorld
from iTasks.Internal.Task     import :: ConnectionTask, :: TaskException
from iTasks.Engine            import :: StartupTask
from iTasks.SDS.Definition    import :: Shared, class Readable, class Identifiable
from iTasks.Internal.IWorld   import :: IOTaskInstance

//Core task server loop
serve :: ![StartupTask] ![(Int,ConnectionTask)] (*IWorld -> (?Timeout,*IWorld)) *IWorld -> *IWorld
loop :: !(*IWorld -> (?Timeout,*IWorld)) !*IWorld -> *IWorld

//Dynamically add a listener
addListener :: !TaskId !Int !Bool !(ConnectionTask) !*IWorld -> (!MaybeError TaskException (),!*IWorld)

//Dynamically add a connection
addConnection :: !TaskId !String !Int !(?Timeout) !ConnectionTask !*IWorld -> (!MaybeError TaskException (ConnectionId, Dynamic),!*IWorld)

ioStateString :: !IOStates -> String

//Ticks every time the server loops once
tick :: SDSSource () () ()

// Definitions of IO tasks (tcp connections)
:: IOTaskOperations ioChannels readData closeInfo =
	{ readData  :: !(Int [(Int, SelectResult)] *(!ioChannels, !*IWorld) -> *(IOData readData closeInfo, ioChannels, *IWorld))
	, writeData :: !(String                    *(!ioChannels, !*IWorld) -> *(ioChannels, *IWorld))
	, closeIO   :: !(                          *(!ioChannels, !*IWorld) -> *IWorld)
	}
:: IOData data closeInfo
	= IODClosed closeInfo
	| IODNoData
	| IODData !data & TC data


//* Creates and adds an IOtask, N.B. The SDS must be synchronous
addIOTask :: 
	!TaskId
	!(Shared sds Dynamic)
	!(*IWorld -> (MaybeErrorString (!initInfo, !.ioChannels), *IWorld))
	!(IOTaskOperations .ioChannels readData closeInfo)
	!(ConnectionId initInfo Dynamic *IWorld -> (MaybeErrorString Dynamic, ?Dynamic, [String], Bool, *IWorld))
	!(ConnectionId initInfo .ioChannels -> *IOTaskInstance)
	!*IWorld
	-> (!MaybeError TaskException (ConnectionId, Dynamic), !*IWorld) | Readable sds
