{- |
Module                  : DrCabal.Profile
Copyright               : (c) 2022 Dmitrii Kovanikov
SPDX-License-Identifier : MPL-2.0
Maintainer              : Dmitrii Kovanikov <kovanikov@gmail.com>
Stability               : Experimental
Portability             : Portable

@dr-cabal profile@ command.
-}

module DrCabal.Profile
    ( runProfile
    ) where

import Colourista.Short (u)
import Data.Aeson (eitherDecodeFileStrict')
import System.Console.ANSI (getTerminalSize)

import DrCabal.Cli (ProfileArgs (..))
import DrCabal.Model (Entry (..), Style (Stacked))
import DrCabal.Profile.Stacked (createStackedChart)

import qualified Colourista

runProfile :: ProfileArgs -> IO ()
runProfile :: ProfileArgs -> IO ()
runProfile ProfileArgs{FilePath
Style
profileArgsStyle :: ProfileArgs -> Style
profileArgsInput :: ProfileArgs -> FilePath
profileArgsStyle :: Style
profileArgsInput :: FilePath
..} = do
    Int
terminalWidth <- IO (Maybe (Int, Int))
getTerminalSize forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Just (Int
_height, Int
width) -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
width
        Maybe (Int, Int)
Nothing -> do
            forall (m :: * -> *). MonadIO m => Text -> m ()
putText forall a b. (a -> b) -> a -> b
$ forall t. IsText t "unlines" => [t] -> t
unlines
                [ Text
"Error getting the terminal width. If you see this error, open an issue"
                , Text
"in the 'dr-cabal' issue tracker and provide as many details as possible"
                , Text
""
                , Text
"  * " forall a. Semigroup a => a -> a -> a
<> forall str. (IsString str, Semigroup str) => str -> str
u Text
"https://github.com/chshersh/dr-cabal/issues/new"
                ]
            forall (m :: * -> *) a. MonadIO m => m a
exitFailure

    [Entry]
entries <- FilePath -> IO [Entry]
readFromFile FilePath
profileArgsInput

    let chart :: Text
chart = case Style
profileArgsStyle of
          Style
Stacked -> Int -> [Entry] -> Text
createStackedChart Int
terminalWidth [Entry]
entries

    forall (m :: * -> *). MonadIO m => Text -> m ()
putTextLn Text
chart

readFromFile :: FilePath -> IO [Entry]
readFromFile :: FilePath -> IO [Entry]
readFromFile FilePath
file = forall a. FromJSON a => FilePath -> IO (Either FilePath a)
eitherDecodeFileStrict' FilePath
file forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Left FilePath
err -> do
        Text -> IO ()
Colourista.errorMessage forall a b. (a -> b) -> a -> b
$ Text
"Error parsing file: " forall a. Semigroup a => a -> a -> a
<> forall a. ToText a => a -> Text
toText FilePath
file
        Text -> IO ()
Colourista.redMessage   forall a b. (a -> b) -> a -> b
$ Text
"      " forall a. Semigroup a => a -> a -> a
<> forall a. ToText a => a -> Text
toText FilePath
err
        forall (m :: * -> *) a. MonadIO m => m a
exitFailure
    Right [Entry]
entries -> forall (f :: * -> *) a. Applicative f => a -> f a
pure [Entry]
entries