{-# LANGUAGE PatternGuards, TupleSections #-}

module Input.Set(setStackage, setPlatform, setGHC) where

import Control.Applicative
import Data.List.Extra
import System.IO.Extra
import qualified Data.Set as Set
import Prelude


-- | Return information about which items are in a particular set.
setStackage :: FilePath -> IO (Set.Set String)
setStackage :: String -> IO (Set String)
setStackage String
file = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList ([String] -> Set String)
-> (String -> [String]) -> String -> Set String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [String]
forall {a}. [a]
stackOverflow) ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
f ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines (String -> Set String) -> IO String -> IO (Set String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
readFile' String
file
    where
        stackOverflow :: [a]
stackOverflow = [] -- ["telegram-api","pinchot","gogol-dfareporting"] -- see https://github.com/ndmitchell/hoogle/issues/167

        f :: [String] -> [String]
f (String
x:[String]
xs) | Just String
x <- String -> String -> Maybe String
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix String
"constraints:" String
x =
                    (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((String, String) -> String
forall a b. (a, b) -> a
fst ((String, String) -> String)
-> (String -> (String, String)) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> (String, String)
word1) ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (String
" " String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf`) ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ (Char
' 'Char -> String -> String
forall a. a -> [a] -> [a]
:String
x) String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
xs
                 | Bool
otherwise = [String] -> [String]
f [String]
xs
        f [] = []


setPlatform :: FilePath -> IO (Set.Set String)
setPlatform :: String -> IO (Set String)
setPlatform String
file = String -> [String] -> IO (Set String)
setPlatformWith String
file [String
"incGHCLib",String
"incLib"]

setPlatformWith :: FilePath -> [String] -> IO (Set.Set String)
setPlatformWith :: String -> [String] -> IO (Set String)
setPlatformWith String
file [String]
names = do
    [String]
src <- String -> [String]
lines (String -> [String]) -> IO String -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
readFile' String
file
    Set String -> IO (Set String)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Set String -> IO (Set String)) -> Set String -> IO (Set String)
forall a b. (a -> b) -> a -> b
$ [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList [String -> String
forall a. Read a => String -> a
read String
lib | String
",":String
name:String
lib:[String]
_ <- (String -> [String]) -> [String] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map String -> [String]
words [String]
src, String
name String -> [String] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
names]

setGHC :: FilePath -> IO (Set.Set String)
setGHC :: String -> IO (Set String)
setGHC String
file = String -> [String] -> IO (Set String)
setPlatformWith String
file [String
"incGHCLib"]