-- | Primary interface for looking up the programming language of a file or
-- interacting with languages known to linguist (https://github.com/github/linguist).
module Data.Languages
  ( languagesForPath
  , languages
  , languagesByExtension
  , languagesByFileName
  , LanguageKey
  , Language(..)
  ) where

import           Control.Applicative
import qualified Data.Map.Strict as Map
import           Data.Maybe
import           Data.Text (Text)
import qualified Data.Text as Text
import           Gen_Languages
import           System.FilePath.Posix

-- | Find the set of possible languages for a given file path.
--
-- Multiple results will be returned for ambiguous files; for example, @.md@ files can be Markdown or GCC machine descriptions, and @.php@ files can be PHP or Hack source files.
languagesForPath :: FilePath -> [Language]
languagesForPath :: FilePath -> [Language]
languagesForPath FilePath
path = [Language]
languageForFileName [Language] -> [Language] -> [Language]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Language]
languageForExtension
  where
    languageForFileName :: [Language]
languageForFileName = FilePath -> Map Text [Text] -> [Language]
languageFor (FilePath -> FilePath
takeFileName FilePath
path) Map Text [Text]
languagesByFileName
    languageForExtension :: [Language]
languageForExtension = FilePath -> Map Text [Text] -> [Language]
languageFor (FilePath -> FilePath
takeExtension FilePath
path) Map Text [Text]
languagesByExtension
    languageFor :: String -> Map.Map Text [LanguageKey] -> [Language]
    languageFor :: FilePath -> Map Text [Text] -> [Language]
languageFor FilePath
k
      = (Text -> [Language]) -> [Text] -> [Language]
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Maybe Language -> [Language]
forall a. Maybe a -> [a]
maybeToList (Maybe Language -> [Language])
-> (Text -> Maybe Language) -> Text -> [Language]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Map Text Language -> Maybe Language)
-> Map Text Language -> Text -> Maybe Language
forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> Map Text Language -> Maybe Language
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Map Text Language
languages)
      ([Text] -> [Language])
-> (Map Text [Text] -> [Text]) -> Map Text [Text] -> [Language]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Maybe [Text] -> [Text]
forall a. a -> Maybe a -> a
fromMaybe []
      (Maybe [Text] -> [Text])
-> (Map Text [Text] -> Maybe [Text]) -> Map Text [Text] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Map Text [Text] -> Maybe [Text]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (FilePath -> Text
Text.pack FilePath
k)