{-# LANGUAGE LambdaCase                 #-}
{-# LANGUAGE MultiWayIf                 #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE RecordWildCards            #-}
{-# LANGUAGE ScopedTypeVariables        #-}
{-# LANGUAGE TupleSections              #-}

module HS.Install(install) where

import qualified Data.Text              as T
import           HS.Managers
import           HS.Types
import           System.IO


-- | call out to the configured installer to install a bindist
install :: Cfg -> InstallMode -> Compiler -> IO Installation
install :: Cfg -> InstallMode -> Compiler -> IO Installation
install Cfg
cfg InstallMode
im Compiler
cp = case Managers -> [Manager]
getManagers (Managers -> [Manager]) -> Managers -> [Manager]
forall a b. (a -> b) -> a -> b
$ Cfg -> Managers
_cfg_managers Cfg
cfg of
  []    -> Compiler -> String -> IO Installation
forall a. Compiler -> String -> IO a
not_found Compiler
cp String
"no managers"
  Manager
mgr:[Manager]
_ -> case InstallMode
im of
    InstallMode
IM_no_install  -> Compiler -> String -> IO Installation
forall a. Compiler -> String -> IO a
not_found Compiler
cp String
"not in auto-installing mode"
    InstallMode
IM_install     -> Cfg -> Manager -> Compiler -> IO Installation
install' Cfg
cfg Manager
mgr Compiler
cp
    InstallMode
IM_ask_install -> do
        Bool
yup <- Compiler -> IO Bool
ask Compiler
cp
        if | Bool
yup -> Cfg -> Manager -> Compiler -> IO Installation
install' Cfg
cfg Manager
mgr Compiler
cp
           | Bool
otherwise -> Compiler -> String -> IO Installation
forall a. Compiler -> String -> IO a
not_found Compiler
cp String
"declined"

ask :: Compiler -> IO Bool
ask :: Compiler -> IO Bool
ask Compiler
cp = do
    BufferMode
bm <- Handle -> IO BufferMode
hGetBuffering Handle
stderr
    Handle -> BufferMode -> IO ()
hSetBuffering Handle
stderr BufferMode
NoBuffering
    Handle -> String -> IO ()
hPutStrLn Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Builder
"toolchain "Builder -> Builder -> String
forall b. FromBuilder b => Builder -> Builder -> b
+|Compiler
cpCompiler -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+Builder
" is required but not installed"
    Handle -> String -> IO ()
hPutStr   Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"would you like to install it? (y/n) : "
    Text
tx <- Text -> Text
T.strip (Text -> Text) -> (String -> Text) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> IO String -> IO Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO String
getLine
    Handle -> BufferMode -> IO ()
hSetBuffering Handle
stderr BufferMode
bm
    Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ Text
tx Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"y",Text
"yes"]

install' :: Cfg -> Manager -> Compiler -> IO Installation
install' :: Cfg -> Manager -> Compiler -> IO Installation
install' Cfg
cfg Manager
mgr Compiler
cp
    | Manager
mgrManager -> Manager -> Bool
forall a. Eq a => a -> a -> Bool
==Manager
stack = Cfg -> CompilerVersion -> IO Installation
installStack Cfg
cfg CompilerVersion
cv
    | Manager
mgrManager -> Manager -> Bool
forall a. Eq a => a -> a -> Bool
==Manager
ghcup = Cfg -> CompilerVersion -> IO Installation
installGhcup Cfg
cfg CompilerVersion
cv
    | Bool
otherwise  = Compiler -> String -> IO Installation
forall a. Compiler -> String -> IO a
not_found Compiler
cp (String -> IO Installation) -> String -> IO Installation
forall a b. (a -> b) -> a -> b
$ Builder
"manager "Builder -> Builder -> String
forall b. FromBuilder b => Builder -> Builder -> b
+|Manager
mgrManager -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+Builder
" not recognised"
  where
    cv :: CompilerVersion
cv = Cfg -> Compiler -> CompilerVersion
resolveCompilerVersion Cfg
cfg Compiler
cp

not_found :: Compiler -> String -> IO a
not_found :: Compiler -> String -> IO a
not_found Compiler
cp String
ctx = String -> IO a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> IO a) -> String -> IO a
forall a b. (a -> b) -> a -> b
$ Builder
"toolchain "Builder -> Builder -> String
forall b. FromBuilder b => Builder -> Builder -> b
+|Compiler
cpCompiler -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+Builder
" not installed ("Builder -> Builder -> Builder
forall b. FromBuilder b => Builder -> Builder -> b
+|String
ctxString -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+Builder
")"