{-# LANGUAGE PatternGuards #-}

module CabalBounds.Drop
   ( drop
   ) where

import Prelude hiding (drop)
import Control.Lens
import CabalBounds.Bound (DropBound(..))
import CabalBounds.Dependencies (Dependencies, filterDependency, dependencyIf)
import qualified CabalLenses as CL
import Data.List (foldl')
import Distribution.PackageDescription (GenericPackageDescription)
import Distribution.Package (Dependency(..))
import Distribution.Version (UpperBound(..), anyVersion)


drop :: DropBound -> [CL.Section] -> Dependencies -> GenericPackageDescription -> GenericPackageDescription
drop :: DropBound
-> [Section]
-> Dependencies
-> GenericPackageDescription
-> GenericPackageDescription
drop DropBound
bound [Section]
sections Dependencies
deps GenericPackageDescription
pkgDescrp =
   (GenericPackageDescription -> Section -> GenericPackageDescription)
-> GenericPackageDescription
-> [Section]
-> GenericPackageDescription
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' GenericPackageDescription -> Section -> GenericPackageDescription
dropFromSection GenericPackageDescription
pkgDescrp [Section]
sections
   where
      dropFromSection :: GenericPackageDescription -> Section -> GenericPackageDescription
dropFromSection GenericPackageDescription
pkgDescrp Section
section =
         GenericPackageDescription
pkgDescrp GenericPackageDescription
-> (GenericPackageDescription -> GenericPackageDescription)
-> GenericPackageDescription
forall a b. a -> (a -> b) -> b
& CondVars
-> Section -> Traversal' GenericPackageDescription Dependency
dependencyIf CondVars
condVars Section
section ((Dependency -> Identity Dependency)
 -> GenericPackageDescription -> Identity GenericPackageDescription)
-> ((Dependency -> Identity Dependency)
    -> Dependency -> Identity Dependency)
-> (Dependency -> Identity Dependency)
-> GenericPackageDescription
-> Identity GenericPackageDescription
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Dependency -> Identity Dependency)
-> Dependency -> Identity Dependency
filterDep ((Dependency -> Identity Dependency)
 -> GenericPackageDescription -> Identity GenericPackageDescription)
-> (Dependency -> Dependency)
-> GenericPackageDescription
-> GenericPackageDescription
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Dependency -> Dependency
dropFromDep

      filterDep :: (Dependency -> Identity Dependency)
-> Dependency -> Identity Dependency
filterDep   = Dependencies -> Traversal' Dependency Dependency
filterDependency Dependencies
deps
      dropFromDep :: Dependency -> Dependency
dropFromDep = DropBound -> Dependency -> Dependency
dropFromDependency DropBound
bound
      condVars :: CondVars
condVars    = GenericPackageDescription -> CondVars
CL.fromDefaults GenericPackageDescription
pkgDescrp


dropFromDependency :: DropBound -> Dependency -> Dependency
dropFromDependency :: DropBound -> Dependency -> Dependency
dropFromDependency DropBound
DropUpper Dependency
dep = Dependency
dep Dependency -> (Dependency -> Dependency) -> Dependency
forall a b. a -> (a -> b) -> b
& (VersionRange -> Identity VersionRange)
-> Dependency -> Identity Dependency
Lens' Dependency VersionRange
CL.versionRange ((VersionRange -> Identity VersionRange)
 -> Dependency -> Identity Dependency)
-> ((UpperBound -> Identity UpperBound)
    -> VersionRange -> Identity VersionRange)
-> (UpperBound -> Identity UpperBound)
-> Dependency
-> Identity Dependency
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([VersionInterval] -> Identity [VersionInterval])
-> VersionRange -> Identity VersionRange
Iso' VersionRange [VersionInterval]
CL.intervals (([VersionInterval] -> Identity [VersionInterval])
 -> VersionRange -> Identity VersionRange)
-> ((UpperBound -> Identity UpperBound)
    -> [VersionInterval] -> Identity [VersionInterval])
-> (UpperBound -> Identity UpperBound)
-> VersionRange
-> Identity VersionRange
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VersionInterval -> Identity VersionInterval)
-> [VersionInterval] -> Identity [VersionInterval]
forall (f :: * -> *) a b.
Traversable f =>
IndexedTraversal Int (f a) (f b) a b
IndexedTraversal
  Int
  [VersionInterval]
  [VersionInterval]
  VersionInterval
  VersionInterval
traversed ((VersionInterval -> Identity VersionInterval)
 -> [VersionInterval] -> Identity [VersionInterval])
-> ((UpperBound -> Identity UpperBound)
    -> VersionInterval -> Identity VersionInterval)
-> (UpperBound -> Identity UpperBound)
-> [VersionInterval]
-> Identity [VersionInterval]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UpperBound -> Identity UpperBound)
-> VersionInterval -> Identity VersionInterval
Lens' VersionInterval UpperBound
CL.upperBound ((UpperBound -> Identity UpperBound)
 -> Dependency -> Identity Dependency)
-> UpperBound -> Dependency -> Dependency
forall s t a b. ASetter s t a b -> b -> s -> t
.~ UpperBound
NoUpperBound
dropFromDependency DropBound
DropBoth  Dependency
dep = Dependency
dep Dependency -> (Dependency -> Dependency) -> Dependency
forall a b. a -> (a -> b) -> b
& (VersionRange -> Identity VersionRange)
-> Dependency -> Identity Dependency
Lens' Dependency VersionRange
CL.versionRange ((VersionRange -> Identity VersionRange)
 -> Dependency -> Identity Dependency)
-> VersionRange -> Dependency -> Dependency
forall s t a b. ASetter s t a b -> b -> s -> t
.~ VersionRange
anyVersion