{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}

-- | Copyright: (c) 2020-2021 berberman
-- SPDX-License-Identifier: MIT
-- Maintainer: berberman <berberman@yandex.com>
-- Stability: experimental
-- Portability: portable
-- This module supports <https://aur.archlinux.org/ AUR> searching.
module Distribution.ArchHs.Aur
  ( Aur,
    isInAur,
    aurToIO,
  )
where

import qualified Data.Text as T
import Distribution.ArchHs.Exception
import Distribution.ArchHs.Internal.Prelude
import Distribution.ArchHs.Name
import Distribution.ArchHs.Types
import Network.HTTP.Client (Manager)
import Web.ArchLinux

-- | AUR Effect
data Aur m a where
  IsInAur :: HasMyName n => n -> Aur m Bool

makeSem_ ''Aur

-- | Check whether a __haskell__ package exists in AUR
isInAur :: (HasMyName n, Member Aur r) => n -> Sem r Bool

-- | Run 'Aur' effect.
aurToIO :: Manager -> Members [WithMyErr, Embed IO] r => Sem (Aur ': r) a -> Sem r a
aurToIO :: Manager
-> Members '[WithMyErr, Embed IO] r => Sem (Aur : r) a -> Sem r a
aurToIO Manager
manager = (forall x (rInitial :: EffectRow). Aur (Sem rInitial) x -> Sem r x)
-> Sem (Aur : r) a -> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall x (rInitial :: EffectRow). e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret ((forall x (rInitial :: EffectRow).
  Aur (Sem rInitial) x -> Sem r x)
 -> Sem (Aur : r) a -> Sem r a)
-> (forall x (rInitial :: EffectRow).
    Aur (Sem rInitial) x -> Sem r x)
-> Sem (Aur : r) a
-> Sem r a
forall a b. (a -> b) -> a -> b
$ \case
  (IsInAur name) -> do
    Either ClientError (AurResponse [AurSearch])
result <- IO (Either ClientError (AurResponse [AurSearch]))
-> Sem r (Either ClientError (AurResponse [AurSearch]))
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO (Either ClientError (AurResponse [AurSearch]))
 -> Sem r (Either ClientError (AurResponse [AurSearch])))
-> (String -> IO (Either ClientError (AurResponse [AurSearch])))
-> String
-> Sem r (Either ClientError (AurResponse [AurSearch]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Manager
-> APIClient 'Aur (AurResponse [AurSearch])
-> IO (Either ClientError (AurResponse [AurSearch]))
forall (s :: APIType) a.
HasBaseUrl s =>
Manager -> APIClient s a -> IO (Either ClientError a)
runAPIClient Manager
manager (APIClient 'Aur (AurResponse [AurSearch])
 -> IO (Either ClientError (AurResponse [AurSearch])))
-> (String -> APIClient 'Aur (AurResponse [AurSearch]))
-> String
-> IO (Either ClientError (AurResponse [AurSearch]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AurSearchType -> Text -> APIClient 'Aur (AurResponse [AurSearch])
searchAur AurSearchType
ByName (Text -> APIClient 'Aur (AurResponse [AurSearch]))
-> (String -> Text)
-> String
-> APIClient 'Aur (AurResponse [AurSearch])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Sem r (Either ClientError (AurResponse [AurSearch])))
-> String -> Sem r (Either ClientError (AurResponse [AurSearch]))
forall a b. (a -> b) -> a -> b
$ ArchLinuxName -> String
unArchLinuxName (ArchLinuxName -> String) -> (n -> ArchLinuxName) -> n -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> ArchLinuxName
forall n. HasMyName n => n -> ArchLinuxName
toArchLinuxName (n -> String) -> n -> String
forall a b. (a -> b) -> a -> b
$ n
name
    case Either ClientError (AurResponse [AurSearch])
result of
      Left ClientError
err -> MyException -> Sem r x
forall e (r :: EffectRow) a.
MemberWithError (Error e) r =>
e -> Sem r a
throw (MyException -> Sem r x) -> MyException -> Sem r x
forall a b. (a -> b) -> a -> b
$ ClientError -> MyException
NetworkException ClientError
err
      Right AurResponse {$sel:_results:AurResponse :: forall a. AurResponse a -> a
_results = [AurSearch
_]} -> Bool -> Sem r Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
      Either ClientError (AurResponse [AurSearch])
_ -> Bool -> Sem r Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False