module Language.Dickinson.Import ( resolveImport
                                 ) where

import           Control.Monad           (filterM)
import           Control.Monad.IO.Class  (MonadIO (..))
import           Data.Maybe              (listToMaybe)
import           Data.Semigroup          ((<>))
import qualified Data.Text               as T
import           Language.Dickinson.Name
import           System.Directory        (doesFileExist)
import           System.FilePath         ((</>))

-- TODO: dependency analysis

-- | The canonical way of resolving imports from a name.
--
-- Returns 'Nothing' if no such file exists.
resolveImport :: MonadIO m
              => [FilePath] -- ^ Places to look
              -> Name a
              -> m (Maybe FilePath)
resolveImport :: forall (m :: * -> *) a.
MonadIO m =>
[FilePath] -> Name a -> m (Maybe FilePath)
resolveImport [FilePath]
incl Name a
n = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> Maybe a
listToMaybe
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM FilePath -> IO Bool
doesFileExist
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FilePath -> FilePath -> FilePath
</> forall a. Name a -> FilePath
getFileName Name a
n) forall a b. (a -> b) -> a -> b
$ [FilePath]
incl

getFileName :: Name a -> FilePath
getFileName :: forall a. Name a -> FilePath
getFileName = (forall a. Semigroup a => a -> a -> a
<> FilePath
".dck") forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr FilePath -> FilePath -> FilePath
(</>) forall a. Monoid a => a
mempty forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> FilePath
T.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Name a -> NonEmpty Text
name