--
-- Demonstrate a fine point of updating records
--


--
-- a partial data structure of an event:
--


type Classification = String

data Signature  = Signature { sigMsg      :: String,
                              sigPriority :: Integer,
                              sigRev      :: Integer,
                              sigSid      :: Integer }
                  deriving (Read, Show)


data ParsedEvent = ParsedEvent { peClass   :: Classification,
                                 peSig     :: Signature }
                   deriving (Read, Show)

data Token = Event   (String, Integer, Integer) |
             Classif (String, Integer)
             deriving (Eq, Show)

t :: [[Token]]
t =  [[Event ("Bad Protocol", 2345, 2), Classif ("Noncritical", 3)],
      [Event ("Port Scan",    3451, 1), Classif ("Important",   2)],
      [Event ("Crowbar",      1123, 2), Classif ("Really Bad",  1)]]


--
-- utility functions for triples
--

fst3 (x, y, z) = x
snd3 (x, y, z) = y
thd3 (x, y, z) = z


--
-- Fill in the fields of the record
--

addField ::  Token -> ParsedEvent -> ParsedEvent
addField t event =
        case t of
                (Event t)     -> event { peSig = Signature {
                                     sigMsg      = fst3 t,
                                     sigSid      = snd3 t,
                                     sigRev      = thd3 t } }

                (Classif t)   -> event { peClass = fst t,
                                         peSig = Signature {
                                     sigPriority = snd t}}


extractFields :: [Token] -> ParsedEvent
extractFields tl =
        foldr addField (ParsedEvent {
                               peClass  = "Snort Alert",
                               peSig    = Signature { sigPriority = 0 } } ) tl



main = do
       print (map extractFields t)