definition module iTasks.Internal.WebService
/**
* This module provides the web service that gives access to tasks via the web.
* It also provides access to upload/download of blob content.
*/
from Internet.HTTP				import :: HTTPRequest, :: HTTPResponse
from iTasks.Engine              import :: WebTask
from iTasks.Internal.IWorld		import :: IWorld
from iTasks.Internal.Task 	    import :: Task, :: ConnectionTask
from iTasks.Internal.TaskIO     import :: TaskOutput, :: TaskOutputMessage
import iTasks.SDS.Definition
from iTasks.UI.Definition           import :: UIChange
from iTasks.WF.Definition	        import :: InstanceNo
from Data.Queue 					import :: Queue
from Data.Map                       import :: Map
from System.Time                    import :: Timespec

:: ConnectionState :== (String, WebSockState,[(InstanceNo,String)])

:: WebSockState =
	{ cur_frame    :: !{#Char}   //The fram
	, message_text :: !Bool     // True -> text message, False -> binary
	, message_data :: ![String] // Message data from previous frames
	}

:: WebSockEvent
	= WSTextMessage String //A UTF-8 text message was received completely
	| WSBinMessage String  //A binary message was received completely
	| WSClose String       //A close frame was received
	| WSPing String        //A ping frame was received

:: WebService r w =
	{ urlMatchPred    :: !?(String -> Bool) // checks whether the URL is served by this service; when none, all requests match
	, completeRequest :: !Bool              // wait for complete request before start serving request
	, onNewReq        :: !(HTTPRequest r                        *IWorld -> *(HTTPResponse,?ConnectionState, ?w, *IWorld))    //* Is called for each new request.
	, onData          :: !(ConnectionId HTTPRequest r String ConnectionState *IWorld -> *([{#Char}], Bool, ConnectionState, ?w, *IWorld)) //* On new data from client.
	, onShareChange   :: !(HTTPRequest r        ConnectionState *IWorld -> *([{#Char}], Bool, ConnectionState, ?w, *IWorld)) //* On shared change.
	, onTick          :: !(HTTPRequest r        ConnectionState *IWorld -> *([{#Char}], Bool, ConnectionState, ?w, *IWorld)) //* Called on each iteration of main loop.
	, onDisconnect    :: !(ConnectionId HTTPRequest r ConnectionState        *IWorld -> *(?w, *IWorld))                                   //* Is called on disconnect.
	}

/**
 * The internal HTTP server.
 *
 * @param Port.
 * @param Base directory.
 * @param Keep-alive time.
 * @param The web services to expose.
 */
httpServer :: !Int !String !Timespec ![WebService r w] (sds () r w) -> ConnectionTask | TC r & TC w & RWShared sds

:: OutputQueues :== Map InstanceNo TaskOutput

/**
 * WebSocket service for tasks.
 *
 * @param Base directory.
 * @param The tasks to serve.
 */
taskUIService :: !String ![WebTask] -> WebService OutputQueues OutputQueues

/**
 * Service for the `/upload` and `/download` endpoints to deal with documents.
 *
 * TODO: The upload and download mechanism used here is inherently insecure!!!
 * A smarter scheme that checks up and downloads, based on the current session
 * / task is needed to prevent unauthorized downloading of documents and DDOS
 * uploading.
 *
 * @param Base directory.
 */
documentService :: !String -> WebService r w

/**
 * Request handler which serves static resources from the application
 * directory, or a system wide default directory if it is not found locally.
 * This request handler is used for serving system wide javascript, css,
 * images, etc.
 *
 * @param Base directory.
 * @param List of task endpoints.
 */
staticResourceService :: !String ![String] -> WebService r w
