--------------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
import Data.Monoid (mappend)
import Hakyll
import Hakyll.Core.Identifier (toFilePath)
import Hakyll.Web.Feed
import System.FilePath
import Text.Regex (mkRegex, splitRegex)



--------------------------------------------------------------------------------
config :: Configuration
config = defaultConfiguration {
   destinationDirectory = "public"
}

feedConfig :: FeedConfiguration
feedConfig = FeedConfiguration {
    feedTitle = "Binary Strolls"
  , feedDescription = "Blag"
  , feedAuthorName = "Dhananjay Balan"
  , feedRoot = "https://blog.dbalan.in"
  , feedAuthorEmail = "blog@dbalan.in"
}

main :: IO ()
main = hakyllWith config $ do
    tags <- buildTags "blog/*" (fromCapture "tags/*.html")

    match "images/*" $ do
        route   idRoute
        compile copyFileCompiler

    match "css/*" $ do
        route   idRoute
        compile compressCssCompiler

    match "fonts/*/*" $ do
      route $ idRoute
      compile copyFileCompiler

    match "notes/*" $ do
      route $ idRoute
      compile copyFileCompiler

    match "blog/*" $ do
        route $  octopressRoute
        compile $ pandocCompiler
            >>= loadAndApplyTemplate "templates/post.html"    (postCtxWTags tags)
            >>= saveSnapshot "content"
            >>= loadAndApplyTemplate "templates/default.html" (postCtxWTags tags)
            >>= relativizeUrls

    match "index.html" $ do
        route idRoute
        compile $ do
            posts <- fmap (take 4) . recentFirst =<< loadAllSnapshots "blog/*" "content"
            let indexCtx =
                    listField "posts" postCtx (return $ take 8 posts) `mappend`
                    constField "title" "Home"                `mappend`
                    defaultContext

            getResourceBody
                >>= applyAsTemplate indexCtx
                >>= loadAndApplyTemplate "templates/default.html" indexCtx
                >>= relativizeUrls

    create ["archive.html"] $ do
        route idRoute
        compile $ do
            posts <- recentFirst =<< loadAll "blog/*"
            let archiveCtx =
                    listField "posts" postCtx (return posts) `mappend`
                    constField "title" "Archives"            `mappend`
                    defaultContext

            makeItem ""
                >>= loadAndApplyTemplate "templates/archive.html" archiveCtx
                >>= loadAndApplyTemplate "templates/default.html" archiveCtx
                >>= relativizeUrls

    -- tags!
    tagsRules tags $ \tag pattern -> do
        let title = "Posts tagged \"" ++ tag ++ "\""
        route idRoute
        compile $ do
            posts <- recentFirst =<< loadAll pattern
            let ctx = constField "title" title
                      `mappend` listField "posts" (postCtxWTags tags) (return posts)
                      `mappend` defaultContext

            makeItem ""
                >>= loadAndApplyTemplate "templates/tag.html" ctx
                >>= loadAndApplyTemplate "templates/default.html" ctx
                >>= relativizeUrls

    create ["atom.xml"] $ do
      route idRoute
      compile $ do
        posts <- fmap (take 5) . recentFirst =<< loadAllSnapshots "blog/*" "content"
        let feedCtx = postCtx `mappend` bodyField "description"
        renderAtom feedConfig feedCtx posts
    match "templates/*" $ compile templateBodyCompiler

--------------------------------------------------------------------------------
extractTags :: Rules Tags
extractTags = do
  tags <- buildTags ("blogs/**" .&&. hasNoVersion) $ fromCapture "tags/*.html"
  return $ sortTagsBy caseInsensitiveTags tags

postCtxWTags :: Tags -> Context String
postCtxWTags tags = tagsField "tags" tags <> postCtx

postCtx :: Context String
postCtx =
    dateField "date" "%B %e, %Y" `mappend`
    defaultContext

-- octopress compatible routes
octopressRoute :: Routes
octopressRoute = customRoute $ octoMangaling

octoMangaling :: Identifier -> FilePath
octoMangaling pathId = base </> year </> month </> day </> post </> "index.html"
  where
    p = toFilePath pathId
    base = takeDirectory p
    seps = splitRegex (mkRegex "-") $ takeBaseName p
    year:month:day:xs = seps
    post = tail $ foldl (\a b -> a ++ "-" ++ b) "" xs
