module Hix.Managed.Handlers.Cabal where

import Data.IORef (IORef, modifyIORef')

import Hix.Class.Map (nFromKeys)
import Hix.Data.Monad (M)
import Hix.Data.PackageName (PackageName)
import Hix.Data.Version (Version)
import Hix.Managed.Cabal.Changes (SolverPlan)
import Hix.Managed.Cabal.Data.SolverState (SolverState)
import Hix.Managed.Data.Constraints (EnvConstraints)
import Hix.Managed.Data.Mutable (MutableDep, MutableVersions, depName)
import Hix.Managed.Data.Mutation (DepMutation)

data CabalHandlers =
  CabalHandlers {
    CabalHandlers -> SolverState -> M (Maybe SolverPlan)
solveForVersion :: SolverState -> M (Maybe SolverPlan),
    CabalHandlers -> PackageName -> Maybe Version
installedVersion :: PackageName -> Maybe Version,
    CabalHandlers -> forall a. [DepMutation a] -> M [DepMutation a]
sortMutations ::  a . [DepMutation a] -> M [DepMutation a]
  }

handlersNull :: CabalHandlers
handlersNull :: CabalHandlers
handlersNull =
  CabalHandlers {
    $sel:solveForVersion:CabalHandlers :: SolverState -> M (Maybe SolverPlan)
solveForVersion = \ SolverState
_ -> Maybe SolverPlan -> M (Maybe SolverPlan)
forall a. a -> M a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe SolverPlan
forall a. Maybe a
Nothing,
    $sel:installedVersion:CabalHandlers :: PackageName -> Maybe Version
installedVersion = Maybe Version -> PackageName -> Maybe Version
forall a b. a -> b -> a
const Maybe Version
forall a. Maybe a
Nothing,
    $sel:sortMutations:CabalHandlers :: forall a. [DepMutation a] -> M [DepMutation a]
sortMutations = [DepMutation a] -> M [DepMutation a]
forall a. a -> M a
forall a. [DepMutation a] -> M [DepMutation a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  }

installedVersions ::
  CabalHandlers ->
  Set MutableDep ->
  MutableVersions
installedVersions :: CabalHandlers -> Set MutableDep -> MutableVersions
installedVersions CabalHandlers
cabal Set MutableDep
names =
  Set MutableDep -> (MutableDep -> Maybe Version) -> MutableVersions
forall (t :: * -> *) map k v sort.
(Foldable t, NMap map k v sort) =>
t k -> (k -> v) -> map
nFromKeys Set MutableDep
names (CabalHandlers
cabal.installedVersion (PackageName -> Maybe Version)
-> (MutableDep -> PackageName) -> MutableDep -> Maybe Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MutableDep -> PackageName
depName)

logCabal :: IORef [(EnvConstraints, Maybe SolverPlan)] -> CabalHandlers -> CabalHandlers
logCabal :: IORef [(EnvConstraints, Maybe SolverPlan)]
-> CabalHandlers -> CabalHandlers
logCabal IORef [(EnvConstraints, Maybe SolverPlan)]
ref CabalHandlers {PackageName -> Maybe Version
SolverState -> M (Maybe SolverPlan)
forall a. [DepMutation a] -> M [DepMutation a]
$sel:solveForVersion:CabalHandlers :: CabalHandlers -> SolverState -> M (Maybe SolverPlan)
$sel:installedVersion:CabalHandlers :: CabalHandlers -> PackageName -> Maybe Version
$sel:sortMutations:CabalHandlers :: CabalHandlers -> forall a. [DepMutation a] -> M [DepMutation a]
solveForVersion :: SolverState -> M (Maybe SolverPlan)
installedVersion :: PackageName -> Maybe Version
sortMutations :: forall a. [DepMutation a] -> M [DepMutation a]
..} =
  CabalHandlers {$sel:solveForVersion:CabalHandlers :: SolverState -> M (Maybe SolverPlan)
solveForVersion = SolverState -> M (Maybe SolverPlan)
solve, [DepMutation a] -> M [DepMutation a]
PackageName -> Maybe Version
forall a. [DepMutation a] -> M [DepMutation a]
$sel:installedVersion:CabalHandlers :: PackageName -> Maybe Version
$sel:sortMutations:CabalHandlers :: forall a. [DepMutation a] -> M [DepMutation a]
installedVersion :: PackageName -> Maybe Version
sortMutations :: forall a. [DepMutation a] -> M [DepMutation a]
..}
  where
    solve :: SolverState -> M (Maybe SolverPlan)
solve SolverState
state = do
      Maybe SolverPlan
plan <- SolverState -> M (Maybe SolverPlan)
solveForVersion SolverState
state
      IO () -> M ()
forall a. IO a -> M a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IORef [(EnvConstraints, Maybe SolverPlan)]
-> ([(EnvConstraints, Maybe SolverPlan)]
    -> [(EnvConstraints, Maybe SolverPlan)])
-> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef [(EnvConstraints, Maybe SolverPlan)]
ref ((SolverState
state.constraints, Maybe SolverPlan
plan) :))
      pure Maybe SolverPlan
plan