{-# LANGUAGE OverloadedStrings #-}

-- | Logic to find the most recent released version of a package.
module LatestVersion (getNewestVersion) where

import Distribution.Types.Version hiding (showVersion)
import Distribution.Text
import qualified Distribution.Package as Cabal

import qualified Data.Text as T
import Network.Wreq
import Data.Aeson
import Control.Monad.Fail
import Control.Lens
import Prelude hiding (fail)

data Resp = Resp { versions :: [Version] }

instance FromJSON Resp where
  parseJSON = withObject "response" $ \o -> do
    versions <- o .: "normal-version"
    versions' <- mapM parseVersion versions
    return $ Resp versions'
    where
      parseVersion :: MonadFail m => String -> m Version
      parseVersion = maybe (fail "failed to parse version") pure . simpleParse


getNewestVersion :: Cabal.PackageName -> IO Version
getNewestVersion pname = do
  resp <- getWith opts url >>= asJSON
  return $ head $ versions (resp ^. responseBody)
  where
    opts = defaults & header "Accept" .~ ["application/json"]
    url = "https://hackage.haskell.org/package/"++(display pname)++"/preferred"