{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DeriveGeneric #-}
module Distribution.Solver.Types.ResolverPackage
    ( ResolverPackage(..)
    , resolverPackageLibDeps
    , resolverPackageExeDeps
    ) where

import Distribution.Solver.Compat.Prelude
import Prelude ()

import Distribution.Solver.Types.InstSolverPackage
import Distribution.Solver.Types.SolverId
import Distribution.Solver.Types.SolverPackage
import qualified Distribution.Solver.Types.ComponentDeps as CD

import Distribution.Compat.Graph (IsNode(..))
import Distribution.Package (Package(..), HasUnitId(..))
import Distribution.Simple.Utils (ordNub)

-- | The dependency resolver picks either pre-existing installed packages
-- or it picks source packages along with package configuration.
--
-- This is like the 'InstallPlan.PlanPackage' but with fewer cases.
--
data ResolverPackage loc = PreExisting InstSolverPackage
                         | Configured  (SolverPackage loc)
  deriving (ResolverPackage loc -> ResolverPackage loc -> Bool
(ResolverPackage loc -> ResolverPackage loc -> Bool)
-> (ResolverPackage loc -> ResolverPackage loc -> Bool)
-> Eq (ResolverPackage loc)
forall loc.
Eq loc =>
ResolverPackage loc -> ResolverPackage loc -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ResolverPackage loc -> ResolverPackage loc -> Bool
$c/= :: forall loc.
Eq loc =>
ResolverPackage loc -> ResolverPackage loc -> Bool
== :: ResolverPackage loc -> ResolverPackage loc -> Bool
$c== :: forall loc.
Eq loc =>
ResolverPackage loc -> ResolverPackage loc -> Bool
Eq, Int -> ResolverPackage loc -> ShowS
[ResolverPackage loc] -> ShowS
ResolverPackage loc -> String
(Int -> ResolverPackage loc -> ShowS)
-> (ResolverPackage loc -> String)
-> ([ResolverPackage loc] -> ShowS)
-> Show (ResolverPackage loc)
forall loc. Show loc => Int -> ResolverPackage loc -> ShowS
forall loc. Show loc => [ResolverPackage loc] -> ShowS
forall loc. Show loc => ResolverPackage loc -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ResolverPackage loc] -> ShowS
$cshowList :: forall loc. Show loc => [ResolverPackage loc] -> ShowS
show :: ResolverPackage loc -> String
$cshow :: forall loc. Show loc => ResolverPackage loc -> String
showsPrec :: Int -> ResolverPackage loc -> ShowS
$cshowsPrec :: forall loc. Show loc => Int -> ResolverPackage loc -> ShowS
Show, (forall x. ResolverPackage loc -> Rep (ResolverPackage loc) x)
-> (forall x. Rep (ResolverPackage loc) x -> ResolverPackage loc)
-> Generic (ResolverPackage loc)
forall x. Rep (ResolverPackage loc) x -> ResolverPackage loc
forall x. ResolverPackage loc -> Rep (ResolverPackage loc) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall loc x. Rep (ResolverPackage loc) x -> ResolverPackage loc
forall loc x. ResolverPackage loc -> Rep (ResolverPackage loc) x
$cto :: forall loc x. Rep (ResolverPackage loc) x -> ResolverPackage loc
$cfrom :: forall loc x. ResolverPackage loc -> Rep (ResolverPackage loc) x
Generic)

instance Binary loc => Binary (ResolverPackage loc)
instance Structured loc => Structured (ResolverPackage loc)

instance Package (ResolverPackage loc) where
  packageId :: ResolverPackage loc -> PackageIdentifier
packageId (PreExisting InstSolverPackage
ipkg)     = InstSolverPackage -> PackageIdentifier
forall pkg. Package pkg => pkg -> PackageIdentifier
packageId InstSolverPackage
ipkg
  packageId (Configured  SolverPackage loc
spkg)     = SolverPackage loc -> PackageIdentifier
forall pkg. Package pkg => pkg -> PackageIdentifier
packageId SolverPackage loc
spkg

resolverPackageLibDeps :: ResolverPackage loc -> CD.ComponentDeps [SolverId]
resolverPackageLibDeps :: ResolverPackage loc -> ComponentDeps [SolverId]
resolverPackageLibDeps (PreExisting InstSolverPackage
ipkg) = InstSolverPackage -> ComponentDeps [SolverId]
instSolverPkgLibDeps InstSolverPackage
ipkg
resolverPackageLibDeps (Configured SolverPackage loc
spkg) = SolverPackage loc -> ComponentDeps [SolverId]
forall loc. SolverPackage loc -> ComponentDeps [SolverId]
solverPkgLibDeps SolverPackage loc
spkg

resolverPackageExeDeps :: ResolverPackage loc -> CD.ComponentDeps [SolverId]
resolverPackageExeDeps :: ResolverPackage loc -> ComponentDeps [SolverId]
resolverPackageExeDeps (PreExisting InstSolverPackage
ipkg) = InstSolverPackage -> ComponentDeps [SolverId]
instSolverPkgExeDeps InstSolverPackage
ipkg
resolverPackageExeDeps (Configured SolverPackage loc
spkg) = SolverPackage loc -> ComponentDeps [SolverId]
forall loc. SolverPackage loc -> ComponentDeps [SolverId]
solverPkgExeDeps SolverPackage loc
spkg

instance IsNode (ResolverPackage loc) where
  type Key (ResolverPackage loc) = SolverId
  nodeKey :: ResolverPackage loc -> Key (ResolverPackage loc)
nodeKey (PreExisting InstSolverPackage
ipkg) = PackageIdentifier -> UnitId -> SolverId
PreExistingId (InstSolverPackage -> PackageIdentifier
forall pkg. Package pkg => pkg -> PackageIdentifier
packageId InstSolverPackage
ipkg) (InstSolverPackage -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId InstSolverPackage
ipkg)
  nodeKey (Configured SolverPackage loc
spkg) = PackageIdentifier -> SolverId
PlannedId (SolverPackage loc -> PackageIdentifier
forall pkg. Package pkg => pkg -> PackageIdentifier
packageId SolverPackage loc
spkg)
  -- Use dependencies for ALL components
  nodeNeighbors :: ResolverPackage loc -> [Key (ResolverPackage loc)]
nodeNeighbors ResolverPackage loc
pkg =
    [SolverId] -> [SolverId]
forall a. Ord a => [a] -> [a]
ordNub ([SolverId] -> [SolverId]) -> [SolverId] -> [SolverId]
forall a b. (a -> b) -> a -> b
$ ComponentDeps [SolverId] -> [SolverId]
forall a. Monoid a => ComponentDeps a -> a
CD.flatDeps (ResolverPackage loc -> ComponentDeps [SolverId]
forall loc. ResolverPackage loc -> ComponentDeps [SolverId]
resolverPackageLibDeps ResolverPackage loc
pkg) [SolverId] -> [SolverId] -> [SolverId]
forall a. [a] -> [a] -> [a]
++
             ComponentDeps [SolverId] -> [SolverId]
forall a. Monoid a => ComponentDeps a -> a
CD.flatDeps (ResolverPackage loc -> ComponentDeps [SolverId]
forall loc. ResolverPackage loc -> ComponentDeps [SolverId]
resolverPackageExeDeps ResolverPackage loc
pkg)