{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE RecordWildCards   #-}
{-# LANGUAGE TypeApplications  #-}

{-|
Module      : Headroom.FileType
Description : Logic for handlig supported file types
Copyright   : (c) 2019-2020 Vaclav Svejcar
License     : BSD-3-Clause
Maintainer  : vaclav.svejcar@gmail.com
Stability   : experimental
Portability : POSIX

Module providing functions for working with the 'FileType', such as performing
detection based on the file extension, etc.
-}

module Headroom.FileType
  ( configByFileType
  , fileTypeByExt
  , listExtensions
  )
where

import           Headroom.Configuration.Types   ( CtHeaderConfig
                                                , CtHeadersConfig
                                                , HeaderConfig(..)
                                                , HeadersConfig(..)
                                                )
import           Headroom.Data.EnumExtra        ( EnumExtra(..) )
import           Headroom.FileType.Types        ( FileType(..) )
import           RIO
import qualified RIO.List                      as L



-- | Returns 'FileType' for given file extension (without dot), using configured
-- values from the 'HeadersConfig'.
fileTypeByExt :: CtHeadersConfig
              -- ^ license headers configuration
              -> Text
              -- ^ file extension (without dot)
              -> Maybe FileType
              -- ^ found 'FileType'
fileTypeByExt :: CtHeadersConfig -> Text -> Maybe FileType
fileTypeByExt CtHeadersConfig
config Text
ext =
  (FileType -> Bool) -> [FileType] -> Maybe FileType
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
L.find (Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem Text
ext ([Text] -> Bool) -> (FileType -> [Text]) -> FileType -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CtHeadersConfig -> FileType -> [Text]
listExtensions CtHeadersConfig
config) (EnumExtra FileType => [FileType]
forall a. EnumExtra a => [a]
allValues @FileType)


-- | Lists all recognized file extensions for given 'FileType', using configured
-- values from the 'HeadersConfig'.
listExtensions :: CtHeadersConfig
               -- ^ license headers configuration
               -> FileType
               -- ^ 'FileType' for which to list extensions
               -> [Text]
               -- ^ list of appropriate file extensions
listExtensions :: CtHeadersConfig -> FileType -> [Text]
listExtensions CtHeadersConfig
config FileType
fileType =
  HeaderConfig 'Complete -> 'Complete ::: [Text]
forall (p :: Phase). HeaderConfig p -> p ::: [Text]
hcFileExtensions (CtHeadersConfig -> FileType -> HeaderConfig 'Complete
configByFileType CtHeadersConfig
config FileType
fileType)


-- | Returns the proper 'HeaderConfig' for the given 'FileType', selected
-- from the 'HeadersConfig'.
configByFileType :: CtHeadersConfig
                 -- ^ license headers configuration
                 -> FileType
                 -- ^ selected 'FileType'
                 -> CtHeaderConfig
                 -- ^ appropriate 'HeaderConfig'
configByFileType :: CtHeadersConfig -> FileType -> HeaderConfig 'Complete
configByFileType HeadersConfig {HeaderConfig 'Complete
hscShell :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscScala :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscRust :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscPureScript :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscJs :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscJava :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscHtml :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscHaskell :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscCss :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscCpp :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscC :: forall (p :: Phase). HeadersConfig p -> HeaderConfig p
hscShell :: HeaderConfig 'Complete
hscScala :: HeaderConfig 'Complete
hscRust :: HeaderConfig 'Complete
hscPureScript :: HeaderConfig 'Complete
hscJs :: HeaderConfig 'Complete
hscJava :: HeaderConfig 'Complete
hscHtml :: HeaderConfig 'Complete
hscHaskell :: HeaderConfig 'Complete
hscCss :: HeaderConfig 'Complete
hscCpp :: HeaderConfig 'Complete
hscC :: HeaderConfig 'Complete
..} FileType
fileType = case FileType
fileType of
  FileType
C          -> HeaderConfig 'Complete
hscC
  FileType
CPP        -> HeaderConfig 'Complete
hscCpp
  FileType
CSS        -> HeaderConfig 'Complete
hscCss
  FileType
Haskell    -> HeaderConfig 'Complete
hscHaskell
  FileType
HTML       -> HeaderConfig 'Complete
hscHtml
  FileType
Java       -> HeaderConfig 'Complete
hscJava
  FileType
JS         -> HeaderConfig 'Complete
hscJs
  FileType
PureScript -> HeaderConfig 'Complete
hscPureScript
  FileType
Rust       -> HeaderConfig 'Complete
hscRust
  FileType
Scala      -> HeaderConfig 'Complete
hscScala
  FileType
Shell      -> HeaderConfig 'Complete
hscShell