module Noli
  ( buildProject,
    buildSite,
    compilePosts,
  )
where

import Control.Monad
  ( unless,
    when,
  )
import Data.ByteString hiding (unpack)
import Data.Text (unpack)
import qualified Data.Text.IO as DT
import Data.Text.Internal (Text)
import Data.Text.Lazy (toStrict)
import Lucid.Base
  ( Html,
    renderText,
  )
import Noli.Types
import PostUtils
  ( compilePost,
    copyFolder,
    extname,
  )
import System.Directory
  ( createDirectory,
    doesDirectoryExist,
    listDirectory,
    removeDirectoryRecursive,
    setCurrentDirectory,
  )

-- | Compile the posts starting from the templates and the folder where the markdown files are.
compilePosts :: PostTemplate -> FilePath -> IO [Post]
compilePosts postCompiler fp = do
  filePaths <- listDirectory fp
  let markdownFilePaths =
        Prelude.map (fp ++) $
          Prelude.filter (\fn -> extname fn == "md") filePaths
  mapM (compilePost postCompiler) markdownFilePaths

-- | Build the dynamic `Project` which works as a basis for the final static site.
--   It takes three arguments and returns a compiled `Project`
buildProject :: Settings -> [Page] -> PostTemplate -> IO Project
buildProject settings pages postCompiler = do
  ps <- compilePosts postCompiler $ posts_location settings
  return Project {posts = ps, pages = pages}

-- | Build the final static site
-- Takes two arguments and creates the files needed for the static site, saving them in the previously-set `dist_location`.
buildSite :: Settings -> Project -> IO ()
buildSite settings' project = do
  distExists <- doesDirectoryExist $ dist_location settings'
  when distExists $ removeDirectoryRecursive $ dist_location settings'
  createDirectory $ dist_location settings'
  copyFolder
    (static_location settings')
    (dist_location settings' ++ "static/")
  setCurrentDirectory $ dist_location settings'
  Prelude.mapM_
    ( \p ->
        DT.writeFile
          (Data.Text.unpack (pagename p) ++ ".html")
          (toStrict $ renderText $ template p)
    )
    (pages project)
  createDirectory "./posts"
  setCurrentDirectory "./posts"
  Prelude.mapM_
    ( \p ->
        DT.writeFile
          (Data.Text.unpack (filename p) ++ ".html")
          (toStrict $ renderText $ compiled_html p)
    )
    (posts project)