{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}

module Logging.Types.Filter ( Filter(..), Filterer ) where

import           Data.List                      (stripPrefix)
import           Data.String
import           Prelude                        hiding (filter)

import           Logging.Types.Class.Filterable
import           Logging.Types.Logger
import           Logging.Types.Record


-- | 'Filter's are used to perform arbitrary filtering of 'LogRecord's.
--
-- 'Sink's and 'Handler's can optionally use 'Filter' to filter records
-- as desired. It allows events which are below a certain point in the
-- sink hierarchy. For example, a filter initialized with "A.B" will allow
-- events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc.
-- but not "A.BB", "B.A.B" etc.
-- If initialized name with the empty string, all events are passed.
newtype Filter = Filter Logger deriving (Read, Show, Eq)

instance IsString Filter where
  fromString = Filter

instance Filterable Filter where
  filter (Filter self) rcd@LogRecord{..}
    | self == "" = True
    | otherwise = case stripPrefix self logger of
                    Just ""      -> True   -- self == logger
                    Just ('.':_) -> True   -- self == parent logger
                    _            -> False


-- |List of Filter
type Filterer = [Filter]