{-# LANGUAGE CPP #-}

-----------------------------------------------------------------------------

-----------------------------------------------------------------------------

{- |
Module      :  Plugins.Monitors.PacmanUpdates
Copyright   :  (c) 2024 Enrico Maria De Angelis
            ,  (c) 2025 Alexander Pankoff
License     :  BSD-style (see LICENSE)

Maintainer  :  Enrico Maria De Angelis <enricomaria.dean6elis@gmail.com>
Stability   :  unstable
Portability :  unportable

A Pacman updates availablility plugin for Xmobar
-}
module Xmobar.Plugins.PacmanUpdates (PacmanUpdates (..)) where

import System.Exit (ExitCode (..))
import System.Process (readProcessWithExitCode)
import Xmobar.Plugins.Command (Rate)
import Xmobar.Run.Exec

data PacmanUpdates = PacmanUpdates (String, String, String, String) Rate
  deriving (ReadPrec [PacmanUpdates]
ReadPrec PacmanUpdates
Int -> ReadS PacmanUpdates
ReadS [PacmanUpdates]
(Int -> ReadS PacmanUpdates)
-> ReadS [PacmanUpdates]
-> ReadPrec PacmanUpdates
-> ReadPrec [PacmanUpdates]
-> Read PacmanUpdates
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS PacmanUpdates
readsPrec :: Int -> ReadS PacmanUpdates
$creadList :: ReadS [PacmanUpdates]
readList :: ReadS [PacmanUpdates]
$creadPrec :: ReadPrec PacmanUpdates
readPrec :: ReadPrec PacmanUpdates
$creadListPrec :: ReadPrec [PacmanUpdates]
readListPrec :: ReadPrec [PacmanUpdates]
Read, Int -> PacmanUpdates -> ShowS
[PacmanUpdates] -> ShowS
PacmanUpdates -> String
(Int -> PacmanUpdates -> ShowS)
-> (PacmanUpdates -> String)
-> ([PacmanUpdates] -> ShowS)
-> Show PacmanUpdates
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PacmanUpdates -> ShowS
showsPrec :: Int -> PacmanUpdates -> ShowS
$cshow :: PacmanUpdates -> String
show :: PacmanUpdates -> String
$cshowList :: [PacmanUpdates] -> ShowS
showList :: [PacmanUpdates] -> ShowS
Show)

instance Exec PacmanUpdates where
  alias :: PacmanUpdates -> String
alias = String -> PacmanUpdates -> String
forall a b. a -> b -> a
const String
"pacman"
  rate :: PacmanUpdates -> Int
rate (PacmanUpdates (String, String, String, String)
_ Int
r) = Int
r
  run :: PacmanUpdates -> IO String
run (PacmanUpdates (String
z, String
o, String
m, String
e) Int
_) = do
    (exit, stdout, _) <- String -> [String] -> String -> IO (ExitCode, String, String)
readProcessWithExitCode String
"checkupdates" [] String
""
    return $ case exit of
      ExitFailure Int
2 -> String
z -- ero updates
      ExitFailure Int
1 -> String
e
      ExitCode
ExitSuccess -> case [String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([String] -> Int) -> [String] -> Int
forall a b. (a -> b) -> a -> b
$ String -> [String]
lines String
stdout of
        Int
0 -> String
forall {a}. a
impossible
        Int
1 -> String
o
        Int
n -> String
m String -> (Char -> String) -> String
forall a b. [a] -> (a -> [b]) -> [b]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Char
c -> if Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'?' then Int -> String
forall a. Show a => a -> String
show Int
n else Char -> String
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure Char
c
      ExitCode
_ -> String
forall {a}. a
impossible
   where
    impossible :: a
impossible = String -> a
forall a. HasCallStack => String -> a
error String
"This is impossible based on pacman manpage"