module Hix.Managed.Handlers.Cabal where

import Data.IORef (IORef, modifyIORef')
import Distribution.PackageDescription (PackageDescription)

import Hix.Class.Map (nFromKeys)
import Hix.Data.Monad (M)
import Hix.Data.PackageId (PackageId)
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 -> PackageId -> Maybe PackageDescription
sourcePackage :: PackageId -> Maybe PackageDescription,
    CabalHandlers -> forall a. [DepMutation a] -> M [DepMutation a]
sortMutations ::  a . [DepMutation a] -> M [DepMutation a]
  }

handlersNull :: CabalHandlers
handlersNull :: CabalHandlers
handlersNull =
  CabalHandlers {
    solveForVersion :: 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,
    installedVersion :: PackageName -> Maybe Version
installedVersion = Maybe Version -> PackageName -> Maybe Version
forall a b. a -> b -> a
const Maybe Version
forall a. Maybe a
Nothing,
    sourcePackage :: PackageId -> Maybe PackageDescription
sourcePackage = Maybe PackageDescription -> PackageId -> Maybe PackageDescription
forall a b. a -> b -> a
const Maybe PackageDescription
forall a. Maybe a
Nothing,
    sortMutations :: 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
PackageId -> Maybe PackageDescription
SolverState -> M (Maybe SolverPlan)
forall a. [DepMutation a] -> M [DepMutation a]
solveForVersion :: CabalHandlers -> SolverState -> M (Maybe SolverPlan)
installedVersion :: CabalHandlers -> PackageName -> Maybe Version
sourcePackage :: CabalHandlers -> PackageId -> Maybe PackageDescription
sortMutations :: CabalHandlers -> forall a. [DepMutation a] -> M [DepMutation a]
solveForVersion :: SolverState -> M (Maybe SolverPlan)
installedVersion :: PackageName -> Maybe Version
sourcePackage :: PackageId -> Maybe PackageDescription
sortMutations :: forall a. [DepMutation a] -> M [DepMutation a]
..} =
  CabalHandlers {solveForVersion :: SolverState -> M (Maybe SolverPlan)
solveForVersion = SolverState -> M (Maybe SolverPlan)
solve, [DepMutation a] -> M [DepMutation a]
PackageName -> Maybe Version
PackageId -> Maybe PackageDescription
forall a. [DepMutation a] -> M [DepMutation a]
installedVersion :: PackageName -> Maybe Version
sourcePackage :: PackageId -> Maybe PackageDescription
sortMutations :: forall a. [DepMutation a] -> M [DepMutation a]
installedVersion :: PackageName -> Maybe Version
sourcePackage :: PackageId -> Maybe PackageDescription
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