{-# LANGUAGE CPP #-}

module Mueval.Context (
    cleanModules,
    defaultModules,
    defaultPackages,
    qualifiedModules,
) where

-----------------------------------------------------------------------------

-- | Return false if any of the listed modules cannot be found in the whitelist.
cleanModules :: [String] -> Bool
cleanModules = all (`elem` defaultModules)

{- | Modules which we should load by default. These are of course whitelisted.
   Specifically, we want the Prelude because otherwise things are horribly
   crippled; we want SimpleReflect so we can do neat things (for said neat
   things, see
   <http://twan.home.fmf.nl/blog/haskell/simple-reflection-of-expressions.details>);
   and we want ShowFun to neuter IO stuff even more.
   The rest should be safe to import without clashes, according to the Lambdabot
   sources.
-}
defaultModules :: [String]
defaultModules =
    [ "Prelude"
    , "ShowFun"
    , "Debug.SimpleReflect"
    , "Data.Function"
    , "Control.Applicative"
    , "Control.Arrow"
    , "Control.Monad"
    , "Control.Monad.Cont"
#if __GLASGOW_HASKELL__ >= 710
    , "Control.Monad.Except"
#else
    , "Control.Monad.Error"
#endif
    , "Control.Monad.Fix"
    , "Control.Monad.Identity"
#if !MIN_VERSION_base(4,7,0)
    , "Control.Monad.Instances"
#endif
    , "Control.Monad.RWS"
    , "Control.Monad.Reader"
    , "Control.Monad.State"
    , "Control.Monad.State"
    , "Control.Monad.Writer"
    , "Data.Array"
    , "Data.Bits"
    , "Data.Bool"
    , "Data.Char"
    , "Data.Complex"
    , "Data.Dynamic"
    , "Data.Either"
    , "Data.Eq"
    , "Data.Fixed"
    , "Data.Graph"
    , "Data.Int"
    , "Data.Ix"
    , "Data.List"
    , "Data.Maybe"
    , "Data.Monoid"
    , {- -- Commented out because they are not necessarily available. If anyone misses
         -- them, perhaps we could look into forcing a dependency on them in the Cabal
         -- file or perhaps enable them via a CLI flag. For now, we'll stash them in a comment.
                     "Control.Parallel",
                     "Control.Parallel.Strategies",
                     "Data.Number.BigFloat",
                     "Data.Number.CReal",
                     "Data.Number.Dif",
                     "Data.Number.Fixed",
                     "Data.Number.Interval",
                     "Data.Number.Natural",
                     "Data.Number.Symbolic",
                     "Math.OEIS",
      -}
      "Data.Ord"
    , "Data.Ratio"
    , "Data.Tree"
    , "Data.Tuple"
    , "Data.Typeable"
    , "Data.Word"
    , "System.Random"
    , "Test.QuickCheck"
    , "Text.PrettyPrint.HughesPJ"
    , "Text.Printf"
    ]

defaultPackages :: [String]
defaultPackages =
    [ "array"
    , "base"
    , "bytestring"
    , "containers"
    ]

{- | Borrowed from Lambdabot, this is the whitelist of modules which should be
   safe to import functions from, but which we don't want to import by
   default.
   FIXME: make these qualified imports. The GHC API & Hint currently do not
   support qualified imports.
   WARNING: You can import these with --module, certainly, but the onus is on
   the user to make sure they fully disambiguate function names; ie:

   > mueval  --module Data.Map -e "Prelude.map (+1) [1..100]"
-}
qualifiedModules :: [(String, Maybe String)]
qualifiedModules =
    [ --                ("Control.Arrow.Transformer", Just "AT"),
      --                ("Control.Arrow.Transformer.All", Just "AT"),
      ("Data.ByteString", Just "BS")
    , ("Data.ByteString.Char8", Just "BSC")
    , ("Data.ByteString.Lazy", Just "BSL")
    , ("Data.ByteString.Lazy.Char8", Just "BSLC")
    , ("Data.Foldable", Just "Data.Foldable")
    , --               ("Data.Generics", Just "Data.Generics"),
      ("Data.IntMap", Just "IM")
    , ("Data.IntSet", Just "IS")
    , ("Data.Map", Just "M")
    , ("Data.Sequence", Just "Data.Sequence")
    , ("Data.Set", Just "S")
    , ("Data.Traversable", Just "Data.Traversable")
    ]
