module Model.Types.TH.Wordlist
  ( wordlist
  ) where

import ClassyPrelude hiding (lift)

import Language.Haskell.TH
import Language.Haskell.TH.Syntax (qAddDependentFile, Lift(..))

import qualified Data.Text as Text
import qualified Data.Text.IO as Text

import qualified Data.Set as Set

import qualified Data.CaseInsensitive as CI
import Data.CaseInsensitive.Instances ()

wordlist :: FilePath -> ExpQ
wordlist file = do
  qAddDependentFile file
  wordlist' <- runIO $ filter ((||) <$> not . isComment <*> isWord) . Text.lines <$> Text.readFile file
  let usedChars = Set.unions $ map (Set.fromList . map CI.mk . Text.unpack) wordlist'
  tupE
    [ listE $ map (\(Text.unpack -> word) -> [e|CI.mk $ Text.pack $(lift word)|]) wordlist'
    , [e|Set.fromDistinctAscList $(lift $ Set.toAscList usedChars)|]
    ]

isWord :: Text -> Bool
isWord t
  | [w] <- Text.words t
  , w == t
  = True
  | otherwise
  = False

isComment :: Text -> Bool
isComment line = or
  [ commentSymbol `Text.isPrefixOf` Text.stripStart line
  , Text.null $ Text.strip line
  ]
  where
    commentSymbol = "#"
