module Imp.Type.Config where

import qualified Control.Monad as Monad
import qualified Control.Monad.Catch as Exception
import qualified Imp.Type.Alias as Alias
import qualified Imp.Type.Flag as Flag
import qualified Imp.Type.Package as Package

data Config = Config
  { Config -> [Alias]
aliases :: [Alias.Alias],
    Config -> Bool
help :: Bool,
    Config -> [Package]
packages :: [Package.Package],
    Config -> Bool
version :: Bool
  }
  deriving (Config -> Config -> Bool
(Config -> Config -> Bool)
-> (Config -> Config -> Bool) -> Eq Config
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Config -> Config -> Bool
== :: Config -> Config -> Bool
$c/= :: Config -> Config -> Bool
/= :: Config -> Config -> Bool
Eq, Int -> Config -> ShowS
[Config] -> ShowS
Config -> String
(Int -> Config -> ShowS)
-> (Config -> String) -> ([Config] -> ShowS) -> Show Config
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Config -> ShowS
showsPrec :: Int -> Config -> ShowS
$cshow :: Config -> String
show :: Config -> String
$cshowList :: [Config] -> ShowS
showList :: [Config] -> ShowS
Show)

initial :: Config
initial :: Config
initial =
  Config
    { aliases :: [Alias]
aliases = [],
      help :: Bool
help = Bool
False,
      packages :: [Package]
packages = [],
      version :: Bool
version = Bool
False
    }

fromFlags :: (Exception.MonadThrow m) => [Flag.Flag] -> m Config
fromFlags :: forall (m :: * -> *). MonadThrow m => [Flag] -> m Config
fromFlags = (Config -> Flag -> m Config) -> Config -> [Flag] -> m Config
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
Monad.foldM Config -> Flag -> m Config
forall (m :: * -> *). MonadThrow m => Config -> Flag -> m Config
applyFlag Config
initial

applyFlag :: (Exception.MonadThrow m) => Config -> Flag.Flag -> m Config
applyFlag :: forall (m :: * -> *). MonadThrow m => Config -> Flag -> m Config
applyFlag Config
config Flag
flag = case Flag
flag of
  Flag.Alias String
string -> do
    Alias
alias <- String -> m Alias
forall (m :: * -> *). MonadThrow m => String -> m Alias
Alias.fromString String
string
    Config -> m Config
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config {aliases = alias : aliases config}
  Flag.Help Bool
bool -> Config -> m Config
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config {help = bool}
  Flag.Package String
string -> do
    Package
package <- String -> m Package
forall (m :: * -> *). MonadThrow m => String -> m Package
Package.fromString String
string
    Config -> m Config
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config {packages = package : packages config}
  Flag.Version Bool
bool -> Config -> m Config
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config {version = bool}