module Data.Aviation.Stratux.HTTP(
  stratuxHTTP
, getStatusWith
, getStatus
, getStatus'
) where

import Control.Applicative((<$>))
import Control.Monad((>>=))
import Control.Monad.Trans.Either(EitherT(EitherT))
import Data.Aeson(eitherDecode, eitherDecode')
import Data.Aviation.Stratux.Types.Status(Status)
import Data.Either(Either)
import Data.Maybe(Maybe(Just))
import Data.String(String)
import Network.HTTP(RequestMethod(GET), simpleHTTP, mkRequest, getResponseBody)
import Network.TCP(HStream)
import Network.URI(URI(URI), URIAuth)
import System.IO(IO)

stratuxHTTP :: 
  HStream b =>
  URIAuth
  -> String
  -> String
  -> String    
  -> IO b
stratuxHTTP auth path query fragment =
  simpleHTTP (mkRequest GET (URI "http:" (Just auth) path query fragment)) >>= getResponseBody

getStatusWith :: 
  HStream x =>
  (x -> Either e a)
  -> URIAuth -- ^ authority @\/\/anonymous\@www.haskell.org:42@
  -> String -- ^ query @?query@
  -> String -- ^ fragment @#frag@
  -> EitherT e IO a
getStatusWith d auth query fragment =
  EitherT (d <$> stratuxHTTP auth "/getStatus" query fragment)

getStatus ::
  URIAuth -- ^ authority @\/\/anonymous\@www.haskell.org:42@
  -> String -- ^ query @?query@
  -> String -- ^ fragment @#frag@
  -> EitherT String IO Status
getStatus =
  getStatusWith eitherDecode

getStatus' ::
  URIAuth -- ^ authority @\/\/anonymous\@www.haskell.org:42@
  -> String -- ^ query @?query@
  -> String -- ^ fragment @#frag@
  -> EitherT String IO Status
getStatus' =
  getStatusWith eitherDecode'