-- We assume we have US-ASCII characters

module Codec.MIME.String.ContentDisposition
      (
       ContentDisposition(ContentDisposition),
       DispositionType(Inline, Attachment),
       DispositionParameter(..),
       get_content_disposition,
      ) where

import Prelude hiding ( (<*>), (<$>), (<*), (<$) )
import Codec.MIME.String.Internal.Utils
import Codec.MIME.String.Internal.ABNF
      (
       Parser, parse, nested_parse,
       (<$>), (<$), (<*>), (<*), (<|>),
       pEOI, pPred, pChar, pMany, pAtLeast,
      )
import Codec.MIME.String.Date (FullDate, p_date_time)
import Codec.MIME.String.Headers
      (
       Parameter, p_parameter,
       cws, p_ci_string, p_extension_token, p_value, p_quoted_string,
      )

data ContentDisposition = ContentDisposition DispositionType
                                             [DispositionParameter]
    deriving (Show, Read)

data DispositionType = Inline | Attachment
    deriving (Show, Read)

data DispositionParameter = Filename String
                          | CreationDate FullDate
                          | ModificationDate FullDate
                          | ReadDate FullDate
                          | Size Integer
                          | DispositionParameter Parameter
    deriving (Show, Read)

get_content_disposition :: String -> Maybe ContentDisposition
get_content_disposition xs
 = case parse ph_content_disposition xs of
       Left cd -> Just cd
       Right _ -> Nothing

ph_content_disposition :: Parser Char ContentDisposition
ph_content_disposition = ContentDisposition
                     <$  cws
                     <*> p_disposition_type
                     <*> pMany (    id
                                <$  cws
                                <*  pChar ';'
                                <*  cws
                                <*> p_disposition_parm)
                     <*  cws
                     <*  pEOI

p_disposition_type :: Parser Char DispositionType
p_disposition_type = Inline <$  p_ci_string "inline"
                 <|> Attachment <$  p_ci_string "attachment"
                 <|> Attachment <$  p_extension_token

p_disposition_parm :: Parser Char DispositionParameter
p_disposition_parm = p_filename_parm
                 <|> p_creation_date_parm
                 <|> p_modification_date_parm
                 <|> p_read_date_parm
                 <|> p_size_parm
                 <|> DispositionParameter <$> p_parameter

p_filename_parm :: Parser Char DispositionParameter
p_filename_parm = Filename
              <$  p_ci_string "filename"
              <*  cws
              <*  pChar '='
              <*  cws
              <*> p_value

p_creation_date_parm :: Parser Char DispositionParameter
p_creation_date_parm = CreationDate
                   <$  p_ci_string "creation-date"
                   <*  cws
                   <*  pChar '='
                   <*  cws
                   <*> p_quoted_date_time

p_modification_date_parm :: Parser Char DispositionParameter
p_modification_date_parm = ModificationDate
                       <$  p_ci_string "modification-date"
                       <*  cws
                       <*  pChar '='
                       <*  cws
                       <*> p_quoted_date_time

p_read_date_parm :: Parser Char DispositionParameter
p_read_date_parm = ReadDate
               <$  p_ci_string "read-date"
               <*  cws
               <*  pChar '='
               <*  cws
               <*> p_quoted_date_time

p_size_parm :: Parser Char DispositionParameter
p_size_parm = (Size . read)
          <$  p_ci_string "size"
          <*  cws
          <*  pChar '='
          <*  cws
          <*> pAtLeast 1 (pPred isAsciiDigit)

p_quoted_date_time :: Parser Char FullDate
p_quoted_date_time = nested_parse p_quoted_string
                                  (id <$> p_date_time <*  pEOI)