{-# LANGUAGE OverloadedStrings #-}

module Elm.File
  ( Spec(..)
  , specsToDir
  ) where

import           Data.List
import           Data.Monoid
import           Data.Text        (Text)
import qualified Data.Text        as T
import qualified Data.Text.IO     as T
import           Formatting       as F
import           System.Directory

makePath :: [Text] -> Text
makePath = T.intercalate "/"

data Spec = Spec
  { namespace    :: [Text]
  , declarations :: [Text]
  }

pathForSpec :: FilePath -> Spec -> [Text]
pathForSpec rootDir spec = T.pack rootDir : namespace spec

ensureDirectory :: FilePath -> Spec -> IO ()
ensureDirectory rootDir spec =
  let dir = makePath . Data.List.init $ pathForSpec rootDir spec
  in createDirectoryIfMissing True (T.unpack dir)

specToFile :: FilePath -> Spec -> IO ()
specToFile rootDir spec =
  let path = pathForSpec rootDir spec
      file = makePath path <> ".elm"
      namespaceText = T.intercalate "." (namespace spec)
      body =
        T.intercalate
          "\n\n"
          (sformat ("module " % F.stext % " exposing (..)") namespaceText :
           declarations spec)
  in do fprint ("Writing: " % F.stext % "\n") file
        T.writeFile (T.unpack file) body

specsToDir :: [Spec] -> FilePath -> IO ()
specsToDir specs rootDir = mapM_ processSpec specs
  where
    processSpec = ensureDirectory rootDir >> specToFile rootDir