{-# LANGUAGE
    FlexibleInstances
  , MultiParamTypeClasses
  , OverloadedStrings
  , TemplateHaskell
  , TypeSynonymInstances
  , UnicodeSyntax
  #-}
-- |An internal module for HTTP version numbers.
module Network.HTTP.Lucu.HttpVersion
    ( HttpVersion(..)
    )
    where
import Control.Applicative
import Control.Applicative.Unicode
import Data.Ascii (Ascii, AsciiBuilder)
import Data.Attoparsec.Char8
import Data.Convertible.Base
import Data.Convertible.Instances.Ascii ()
import Data.Convertible.Utils
import Data.Default
import Data.Monoid.Unicode
import Prelude hiding (min)
import Prelude.Unicode

-- |An HTTP version consists of major and minor versions.
data HttpVersion
    = HttpVersion !Int !Int
      deriving (Eq, Show)

instance Ord HttpVersion where
    (HttpVersion majA minA) `compare` (HttpVersion majB minB)
        | majA > majB = GT
        | majA < majB = LT
        | minA > minB = GT
        | minA < minB = LT
        | otherwise   = EQ

instance ConvertSuccess HttpVersion Ascii where
    {-# INLINE convertSuccess #-}
    convertSuccess = convertSuccessVia (()  AsciiBuilder)

instance ConvertSuccess HttpVersion AsciiBuilder where
    {-# INLINE convertSuccess #-}
    convertSuccess v
        = case v of
            -- Optimisation for special cases.
            HttpVersion 1 0  cs ("HTTP/1.0"  Ascii)
            HttpVersion 1 1  cs ("HTTP/1.1"  Ascii)
            -- General (but almost never occuring) cases.
            HttpVersion maj min
                 cs ("HTTP/"  Ascii)     
                  convertUnsafe (show maj) 
                  cs ("."      Ascii)     
                  convertUnsafe (show min)

deriveAttempts [ ([t| HttpVersion |], [t| Ascii        |])
               , ([t| HttpVersion |], [t| AsciiBuilder |])
               ]

instance Default (Parser HttpVersion) where
    {-# INLINEABLE def #-}
    def = string "HTTP/"
          *>
          (HttpVersion <$> decimal  (char '.' *> decimal))