{-# LANGUAGE DeriveGeneric #-}
module Interfaces.Hoogle 
    ( queryHoogle
    , formatHoogle
    ) where

import Data.Aeson (eitherDecode, FromJSON(..))
import Control.Applicative ((<$>))
import GHC.Generics
import Network.Curl
import Network.HTTP (urlEncode)

import Interfaces.HTML (fetchLazy)

-- |URL to Hoogle's API query
hoogleJSON :: String
hoogleJSON = "http://www.haskell.org/hoogle/?mode=json&start=1&count=3&hoogle="

-- |One set of data we received by parsing the whole JSON reply from
-- Hoogle.
data HoogleSet = HoogleSet { location :: String -- ^ The URL to the API page
                           , self     :: String -- ^ Type definition, etc.
                           , docs     :: String -- ^ Short documentation
                           } deriving (Show, Generic)

data HoogleReply = HoogleReply { version :: String -- ^ Current version of Hoogle.
                               , results :: [HoogleSet] -- ^ A set of results for a query
                               } deriving (Show, Generic)

instance FromJSON HoogleReply
instance FromJSON HoogleSet

-- |Given a query, compose the request
composeQuery :: String -> String
composeQuery = (++) hoogleJSON . urlEncode

formatSet :: HoogleSet -> String
formatSet = self 

formatHoogle :: HoogleReply -> [String]
formatHoogle (HoogleReply _ []) = ["No results found."]
formatHoogle (HoogleReply _ l ) = map formatSet l

-- |Fetch and decode the JSON file. Results in 'Either String HoogleReply',
-- signaling parse status.
queryHoogle :: String -> IO (Either String HoogleReply)
queryHoogle s = eitherDecode <$> respBody <$> fetchLazy (composeQuery s)
