{-|
Module      : Network.Wai.RequestSpec.Error
Description : Error data types and handling for RequestSpec
Copyright   : Allele Dev 2015
License     : BSD-3
Maintainer  : allele.dev@gmail.com
Stability   : experimental
Portability : POSIX
-}
module Network.Wai.RequestSpec.Error (
  Loc(..),
  Reason,
  Error(..),
  toList,
  toTextList
) where

import Data.CaseInsensitive
import Data.Monoid
import Data.Text

data Loc = Header (CI Text) | Param Text

instance Show Loc where
  show (Header l) = "header " <> (unpack . original) l
  show (Param l) = "parameter " <> unpack l

type Reason = Text
data Error
  = Missing Loc
  | Malformed Reason Text
  | Freeform Reason
  | Or Error Error
  | And Error Error
  | Annotation Text
  | Clear

instance Show Error where
  show (Missing l) = "missing " <> show l
  show (Malformed r s) = "could not parse " <> unpack s <> ": " <> unpack r
  show (Freeform r) = unpack r
  show (Or m1 m2) = show m1 <> " | " <> show m2
  show (And a@(Annotation _) m2) = show a <> show m2
  show (And m1 m2) = show m1 <> "\n" <> show m2
  show (Annotation m) = unpack m <> ": "
  show Clear = []

instance Monoid Error where
  mempty = Clear
  mappend = And

toList :: Error -> [String]
toList (Or x1 x2) = toList x1 <> toList x2
toList (And x1 x2) = toList x1 <> toList x2
toList Clear = []
toList e = [show e]

toTextList :: Error -> [Text]
toTextList = fmap pack . toList