{-# LANGUAGE ScopedTypeVariables #-}

-- |
-- Module    : Aura.State
-- Copyright : (c) Colin Woodbury, 2012 - 2020
-- License   : GPL3
-- Maintainer: Colin Woodbury <colin@fosskers.ca>
--
-- Query the AUR for a package's PKGBUILD.

module Aura.Pkgbuild.Fetch
  ( getPkgbuild
  , pkgbuildUrl
  ) where

import           Aura.Types (PkgName(..), Pkgbuild(..))
import           Aura.Utils (urlContents)
import           Network.HTTP.Client (Manager)
import           Network.URI (escapeURIString, isUnescapedInURIComponent)
import           RIO
import           RIO.FilePath ((</>))
import qualified RIO.Text as T

---

baseUrl :: String
baseUrl :: String
baseUrl = String
"https://aur.archlinux.org/"

-- | The location of a given package's PKGBUILD on the AUR servers.
pkgbuildUrl :: String -> String
pkgbuildUrl :: String -> String
pkgbuildUrl String
p = String
baseUrl String -> String -> String
</> String
"cgit/aur.git/plain/PKGBUILD?h="
  String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Char -> Bool) -> String -> String
escapeURIString Char -> Bool
isUnescapedInURIComponent String
p

-- | The PKGBUILD of a given package, retrieved from the AUR servers.
getPkgbuild :: Manager -> PkgName -> IO (Maybe Pkgbuild)
getPkgbuild :: Manager -> PkgName -> IO (Maybe Pkgbuild)
getPkgbuild Manager
m PkgName
p = IO (Maybe Pkgbuild) -> IO (Maybe Pkgbuild)
forall a. IO (Maybe a) -> IO (Maybe a)
e (IO (Maybe Pkgbuild) -> IO (Maybe Pkgbuild))
-> IO (Maybe Pkgbuild) -> IO (Maybe Pkgbuild)
forall a b. (a -> b) -> a -> b
$ do
  Maybe ByteString
t <- Manager -> String -> IO (Maybe ByteString)
urlContents Manager
m (String -> IO (Maybe ByteString))
-> (Text -> String) -> Text -> IO (Maybe ByteString)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
pkgbuildUrl (String -> String) -> (Text -> String) -> Text -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack (Text -> IO (Maybe ByteString)) -> Text -> IO (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ PkgName -> Text
pnName PkgName
p
  Maybe Pkgbuild -> IO (Maybe Pkgbuild)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Pkgbuild -> IO (Maybe Pkgbuild))
-> Maybe Pkgbuild -> IO (Maybe Pkgbuild)
forall a b. (a -> b) -> a -> b
$ (ByteString -> Pkgbuild) -> Maybe ByteString -> Maybe Pkgbuild
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Pkgbuild
Pkgbuild Maybe ByteString
t
  where
    -- TODO Make this less "baby's first Haskell".
    e :: IO (Maybe a) -> IO (Maybe a)
    e :: IO (Maybe a) -> IO (Maybe a)
e IO (Maybe a)
f = IO (Maybe a)
f IO (Maybe a) -> (SomeException -> IO (Maybe a)) -> IO (Maybe a)
forall (m :: * -> *) e a.
(MonadUnliftIO m, Exception e) =>
m a -> (e -> m a) -> m a
`catch` (\(SomeException
_ :: SomeException) -> Maybe a -> IO (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing)