{-|
Module      : IRTS.System
Description : Utilities for interacting with the System.

License     : BSD3
Maintainer  : The Idris Community.
-}
{-# LANGUAGE CPP #-}
module IRTS.System( getIdrisDataFileByName
                  , getCC
                  , getLibFlags
                  , getIdrisDataDir
                  , getIdrisLibDir
                  , getIdrisDocDir
                  , getIdrisCRTSDir
                  , getIdrisJSRTSDir
                  , getIncFlags
                  , getEnvFlags
                  , version
                  ) where

#ifdef FREESTANDING
import Paths_idris (version)
import Target_idris
#else
import Paths_idris
#endif
import BuildFlags_idris

import Data.List.Split
import Data.Maybe (fromMaybe)
import System.Environment
import System.FilePath (addTrailingPathSeparator, dropTrailingPathSeparator,
                        (</>))


getIdrisDataDir :: IO String
getIdrisDataDir :: IO String
getIdrisDataDir = do
  Maybe String
envValue <- String -> IO (Maybe String)
lookupEnv String
"TARGET"
  case Maybe String
envValue of
    Maybe String
Nothing -> do
      String
ddir <- IO String
getDataDir
      String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
ddir
    Just String
ddir -> String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
ddir

getIdrisDataFileByName :: String -> IO FilePath
getIdrisDataFileByName :: String -> IO String
getIdrisDataFileByName String
fn = do
  String
dir <- IO String
getIdrisDataDir
  String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String
dir String -> String -> String
</> String
fn

overrideIdrisSubDirWith :: String  -- ^ Sub directory in `getDataDir` location.
                        -> String  -- ^ Environment variable to get new location from.
                        -> IO FilePath
overrideIdrisSubDirWith :: String -> String -> IO String
overrideIdrisSubDirWith String
fp String
envVar = do
  Maybe String
envValue <- String -> IO (Maybe String)
lookupEnv String
envVar
  case Maybe String
envValue of
    Maybe String
Nothing -> do
      String
ddir <- IO String
getIdrisDataDir
      String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String
ddir String -> String -> String
</> String
fp)
    Just String
ddir -> String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
ddir

getCC :: IO String
getCC :: IO String
getCC = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
cc (Maybe String -> String) -> IO (Maybe String) -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO (Maybe String)
lookupEnv String
"IDRIS_CC"
  where
#ifdef mingw32_HOST_OS
    cc = "gcc"
#else
    cc :: String
cc = String
"cc"
#endif

getEnvFlags :: IO [String]
getEnvFlags :: IO [String]
getEnvFlags = [String] -> (String -> [String]) -> Maybe String -> [String]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (String -> String -> [String]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn String
" ") (Maybe String -> [String]) -> IO (Maybe String) -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO (Maybe String)
lookupEnv String
"IDRIS_CFLAGS"


#if defined(freebsd_HOST_OS) || defined(dragonfly_HOST_OS)\
    || defined(openbsd_HOST_OS) || defined(netbsd_HOST_OS)
extraLib = ["-L/usr/local/lib"]
extraInclude = ["-I/usr/local/include"]
#else
extraLib :: [a]
extraLib = []
extraInclude :: [a]
extraInclude = []
#endif

#ifdef IDRIS_GMP
gmpLib :: [String]
gmpLib = [String
"-lgmp", String
"-DIDRIS_GMP"]
#else
gmpLib = []
#endif

extraLibFlags :: [String]
extraLibFlags = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String
"-L" String -> String -> String
forall a. [a] -> [a] -> [a]
++) [String]
extraLibDirs

getLibFlags :: IO [String]
getLibFlags = do String
dir <- IO String
getIdrisCRTSDir
                 [String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> IO [String]) -> [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ [String]
extraLibFlags
                   [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
forall a. [a]
extraLib
                   [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"-L" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
dropTrailingPathSeparator String
dir, String
"-lidris_rts"]
                   [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
gmpLib
                   [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"-lpthread"]

getIdrisLibDir :: IO String
getIdrisLibDir = String -> String
addTrailingPathSeparator (String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> String -> IO String
overrideIdrisSubDirWith String
"libs" String
"IDRIS_LIBRARY_PATH"

getIdrisDocDir :: IO String
getIdrisDocDir = String -> String
addTrailingPathSeparator (String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> String -> IO String
overrideIdrisSubDirWith String
"docs" String
"IDRIS_DOC_PATH"

getIdrisJSRTSDir :: IO String
getIdrisJSRTSDir = do
  String
ddir <- IO String
getIdrisDataDir
  String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String -> String
addTrailingPathSeparator (String
ddir String -> String -> String
</> String
"jsrts")

getIdrisCRTSDir :: IO String
getIdrisCRTSDir = do
  String
ddir <- IO String
getIdrisDataDir
  String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ String -> String
addTrailingPathSeparator (String
ddir String -> String -> String
</> String
"rts")

getIncFlags :: IO [String]
getIncFlags = do String
dir <- IO String
getIdrisCRTSDir
                 [String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> IO [String]) -> [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ (String
"-I" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
dropTrailingPathSeparator String
dir) String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
forall a. [a]
extraInclude