module StackageToHackage.Hackage.Types where

import StackageToHackage.Stackage.Types (Ghc, Git, GhcOptions, PkgName, FlagName)

import Data.List.NonEmpty (NonEmpty)
import Data.Map.Strict (Map)
import Distribution.Types.PackageId (PackageIdentifier(..))
import Distribution.Types.PackageName (unPackageName)

import qualified Data.Text as T


data Project = Project
    { Project -> Ghc
ghc :: Ghc
    , Project -> NonEmpty FilePath
pkgs :: NonEmpty FilePath
    , Project -> [Git]
srcs :: [Git]
    , Project -> GhcOptions
ghcOpts :: GhcOptions
    } deriving (Int -> Project -> ShowS
[Project] -> ShowS
Project -> FilePath
(Int -> Project -> ShowS)
-> (Project -> FilePath) -> ([Project] -> ShowS) -> Show Project
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [Project] -> ShowS
$cshowList :: [Project] -> ShowS
show :: Project -> FilePath
$cshow :: Project -> FilePath
showsPrec :: Int -> Project -> ShowS
$cshowsPrec :: Int -> Project -> ShowS
Show)


newtype Freeze = Freeze [Constraint] deriving (Int -> Freeze -> ShowS
[Freeze] -> ShowS
Freeze -> FilePath
(Int -> Freeze -> ShowS)
-> (Freeze -> FilePath) -> ([Freeze] -> ShowS) -> Show Freeze
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [Freeze] -> ShowS
$cshowList :: [Freeze] -> ShowS
show :: Freeze -> FilePath
$cshow :: Freeze -> FilePath
showsPrec :: Int -> Freeze -> ShowS
$cshowsPrec :: Int -> Freeze -> ShowS
Show)


data Constraint = VersionPin PackageIdentifier
                | FlagSetting PkgName (Map FlagName Bool)
    deriving (Int -> Constraint -> ShowS
[Constraint] -> ShowS
Constraint -> FilePath
(Int -> Constraint -> ShowS)
-> (Constraint -> FilePath)
-> ([Constraint] -> ShowS)
-> Show Constraint
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [Constraint] -> ShowS
$cshowList :: [Constraint] -> ShowS
show :: Constraint -> FilePath
$cshow :: Constraint -> FilePath
showsPrec :: Int -> Constraint -> ShowS
$cshowsPrec :: Int -> Constraint -> ShowS
Show, Constraint -> Constraint -> Bool
(Constraint -> Constraint -> Bool)
-> (Constraint -> Constraint -> Bool) -> Eq Constraint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Constraint -> Constraint -> Bool
$c/= :: Constraint -> Constraint -> Bool
== :: Constraint -> Constraint -> Bool
$c== :: Constraint -> Constraint -> Bool
Eq)

instance Ord Constraint where
    compare :: Constraint -> Constraint -> Ordering
compare (VersionPin PackageIdentifier
pkg1) (VersionPin PackageIdentifier
pkg2) = PackageIdentifier -> PackageIdentifier -> Ordering
forall a. Ord a => a -> a -> Ordering
compare PackageIdentifier
pkg1 PackageIdentifier
pkg2
    compare (FlagSetting PkgName
pkg1 Map PkgName Bool
_) (FlagSetting PkgName
pkg2 Map PkgName Bool
_) = PkgName -> PkgName -> Ordering
forall a. Ord a => a -> a -> Ordering
compare PkgName
pkg1 PkgName
pkg2
    compare (VersionPin PackageIdentifier
pkg1) (FlagSetting PkgName
pkg2 Map PkgName Bool
_) =
        case PkgName -> PkgName -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (FilePath -> PkgName
T.pack (FilePath -> PkgName)
-> (PackageIdentifier -> FilePath) -> PackageIdentifier -> PkgName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageName -> FilePath
unPackageName (PackageName -> FilePath)
-> (PackageIdentifier -> PackageName)
-> PackageIdentifier
-> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageIdentifier -> PackageName
pkgName (PackageIdentifier -> PkgName) -> PackageIdentifier -> PkgName
forall a b. (a -> b) -> a -> b
$ PackageIdentifier
pkg1) PkgName
pkg2 of
            Ordering
EQ -> Ordering
GT
            Ordering
x -> Ordering
x
    compare (FlagSetting PkgName
pkg1 Map PkgName Bool
_) (VersionPin PackageIdentifier
pkg2) =
        case PkgName -> PkgName -> Ordering
forall a. Ord a => a -> a -> Ordering
compare PkgName
pkg1 (FilePath -> PkgName
T.pack (FilePath -> PkgName)
-> (PackageIdentifier -> FilePath) -> PackageIdentifier -> PkgName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageName -> FilePath
unPackageName (PackageName -> FilePath)
-> (PackageIdentifier -> PackageName)
-> PackageIdentifier
-> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageIdentifier -> PackageName
pkgName (PackageIdentifier -> PkgName) -> PackageIdentifier -> PkgName
forall a b. (a -> b) -> a -> b
$ PackageIdentifier
pkg2) of
            Ordering
EQ -> Ordering
LT
            Ordering
x -> Ordering
x