-------------------------------------------------------------------------
-- 
-- 	Haskell: The Craft of Functional Programming, 3e
-- 	Simon Thompson
-- 	(c) Addison-Wesley, 1996-2011.
--
-- 	The top level of the server simulation.
--
-------------------------------------------------------------------------

module TopLevelServe where

import Base		-- for the base types of the system
import QueueState	-- for the queue type
import ServerState	-- for the server type
import RandomGen	-- for the random inputs


-- The top-level simulation is a function from a series of input 
-- messages to a series of output messages, so

doSimulation :: ServerState -> [Inmess] -> [Outmess]

doSimulation servSt (im:messes)
  = outmesses ++ doSimulation servStNext messes
    where
    (servStNext , outmesses) = simulationStep servSt im

-- How do we generate an input sequence? From RandomGen we have the
-- sequence of times given by randomTimes

simulationInput :: [Inmess] 

simulationInput = zipWith Yes [1 .. ] randomTimes

-- The output generated by the sample input.

simEx :: [Outmess]

simEx = doSimulation serverStart simulationInput

-- 	= [Discharge 1 0 2, Discharge 3 0 1, Discharge 6 0 1, 
-- 	   Discharge 2 0 5, Discharge 5 0 3, Discharge 4 0 4,
-- 	   Discharge 7 2 2,...

-- A `finite' input: infinite list with only a finite number of `interesting'
-- inputs.

simulationInput2 :: [Inmess] 

simulationInput2 = take 50 simulationInput ++ noes

noes = No : noes

-- A finite list of outputs, corresponding to the `finite' list of inputs given by
-- simulationInput2

simEx2 :: [Outmess]

simEx2 = take 50 (doSimulation serverStart simulationInput2)

-- Total waiting time on all the queues

totalWait :: [Outmess] -> Int
totalWait = sum . map waitTime
            where
            waitTime (Discharge _ w _) = w

-- Total wait in the second example.

totalWaitEx2 = totalWait simEx2

