module Rules.Blog.Footer (
    build
) where

import           Control.Monad        (forM_)
import           Control.Monad.Reader (asks, lift)
import           Hakyll
import           System.FilePath      ((</>))

import           Archives             (MonthlyArchives, YearlyArchives,
                                       archivesMap)
import           Config.Blog          (BlogConfig (..))
import           Config.Program       (tmBlogRoot)
import           Contexts             (siteCtx)
import qualified Contexts.Blog        as BlogCtx
import           Contexts.Field       (tagCloudField', yearMonthArchiveField)
import           Rules.Blog.Type
import           Utils                (mconcatM)

build :: Tags
    -> YearlyArchives
    -> MonthlyArchives
    -> BlogConfReader m Rules ()
build :: forall (m :: * -> *).
Tags
-> YearlyArchives -> MonthlyArchives -> BlogConfReader m Rules ()
build Tags
tags YearlyArchives
y MonthlyArchives
m = do
    Identifier
footerPath <- (BlogConfig m -> Identifier)
-> ReaderT (BlogConfig m) Rules Identifier
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ((BlogConfig m -> Identifier)
 -> ReaderT (BlogConfig m) Rules Identifier)
-> (BlogConfig m -> Identifier)
-> ReaderT (BlogConfig m) Rules Identifier
forall a b. (a -> b) -> a -> b
$ FilePath -> Identifier
fromFilePath (FilePath -> Identifier)
-> (BlogConfig m -> FilePath) -> BlogConfig m -> Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
"-footer.html") (FilePath -> FilePath)
-> (BlogConfig m -> FilePath) -> BlogConfig m -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BlogConfig m -> FilePath
forall (m :: * -> *). BlogConfig m -> FilePath
blogName
    Int
pen <- (BlogConfig m -> Int) -> ReaderT (BlogConfig m) Rules Int
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks BlogConfig m -> Int
forall (m :: * -> *). BlogConfig m -> Int
blogPageEntriesNum
    Pattern
ep <- (BlogConfig m -> Pattern) -> ReaderT (BlogConfig m) Rules Pattern
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks BlogConfig m -> Pattern
forall (m :: * -> *). BlogConfig m -> Pattern
blogEntryPattern
    FilePath
cs <- (BlogConfig m -> FilePath) -> ReaderT (BlogConfig m) Rules FilePath
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks BlogConfig m -> FilePath
forall (m :: * -> *). BlogConfig m -> FilePath
blogContentSnapshot
    Context FilePath
pCtxForFooter <- Tags -> BlogConfReader m Rules (Context FilePath)
forall (m :: * -> *) (n :: * -> *).
Monad m =>
Tags -> BlogConfReader n m (Context FilePath)
BlogCtx.postCtx Tags
tags
    Context FilePath
footerCtx <- [BlogConfReader m Rules (Context FilePath)]
-> BlogConfReader m Rules (Context FilePath)
forall (m :: * -> *) b. (Monad m, Monoid b) => [m b] -> m b
mconcatM [
        Context FilePath -> BlogConfReader m Rules (Context FilePath)
forall a. a -> ReaderT (BlogConfig m) Rules a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Context FilePath -> BlogConfReader m Rules (Context FilePath))
-> Context FilePath -> BlogConfReader m Rules (Context FilePath)
forall a b. (a -> b) -> a -> b
$ FilePath -> Tags -> Context FilePath
forall a. FilePath -> Tags -> Context a
tagCloudField' FilePath
"tag-cloud" Tags
tags
      , Context FilePath -> BlogConfReader m Rules (Context FilePath)
forall a. a -> ReaderT (BlogConfig m) Rules a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Context FilePath -> BlogConfReader m Rules (Context FilePath))
-> Context FilePath -> BlogConfReader m Rules (Context FilePath)
forall a b. (a -> b) -> a -> b
$ Context FilePath
siteCtx
      , BlogConfReader m Rules (Context FilePath)
forall (m :: * -> *) (n :: * -> *).
Monad m =>
BlogConfReader n m (Context FilePath)
BlogCtx.footerAdditionalComponent
      ]
    Rules () -> BlogConfReader m Rules ()
forall (m :: * -> *) a.
Monad m =>
m a -> ReaderT (BlogConfig m) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Rules () -> BlogConfReader m Rules ())
-> Rules () -> BlogConfReader m Rules ()
forall a b. (a -> b) -> a -> b
$ [Maybe FilePath] -> (Maybe FilePath -> Rules ()) -> Rules ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Maybe FilePath
forall a. Maybe a
Nothing Maybe FilePath -> [Maybe FilePath] -> [Maybe FilePath]
forall a. a -> [a] -> [a]
: ((FilePath, [Identifier]) -> Maybe FilePath)
-> [(FilePath, [Identifier])] -> [Maybe FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just (FilePath -> Maybe FilePath)
-> ((FilePath, [Identifier]) -> FilePath)
-> (FilePath, [Identifier])
-> Maybe FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath, [Identifier]) -> FilePath
forall a b. (a, b) -> a
fst) (YearlyArchives -> [(FilePath, [Identifier])]
forall k. Archives k -> [(k, [Identifier])]
archivesMap YearlyArchives
y)) ((Maybe FilePath -> Rules ()) -> Rules ())
-> (Maybe FilePath -> Rules ()) -> Rules ()
forall a b. (a -> b) -> a -> b
$ \Maybe FilePath
year -> (Rules () -> Rules ())
-> (FilePath -> Rules () -> Rules ())
-> Maybe FilePath
-> Rules ()
-> Rules ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Rules () -> Rules ()
forall a. a -> a
id FilePath -> Rules () -> Rules ()
version Maybe FilePath
year (Rules () -> Rules ()) -> Rules () -> Rules ()
forall a b. (a -> b) -> a -> b
$
        [Identifier] -> Rules () -> Rules ()
create [Identifier
footerPath] (Rules () -> Rules ()) -> Rules () -> Rules ()
forall a b. (a -> b) -> a -> b
$
            Compiler (Item FilePath) -> Rules ()
forall a.
(Binary a, Typeable a, Writable a) =>
Compiler (Item a) -> Rules ()
compile (Compiler (Item FilePath) -> Rules ())
-> Compiler (Item FilePath) -> Rules ()
forall a b. (a -> b) -> a -> b
$ do
                [Item FilePath]
recent <- ([Item FilePath] -> [Item FilePath])
-> Compiler [Item FilePath] -> Compiler [Item FilePath]
forall a b. (a -> b) -> Compiler a -> Compiler b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> [Item FilePath] -> [Item FilePath]
forall a. Int -> [a] -> [a]
take Int
pen) (Compiler [Item FilePath] -> Compiler [Item FilePath])
-> ([Item FilePath] -> Compiler [Item FilePath])
-> [Item FilePath]
-> Compiler [Item FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  [Item FilePath] -> Compiler [Item FilePath]
forall (m :: * -> *) a.
(MonadMetadata m, MonadFail m) =>
[Item a] -> m [Item a]
recentFirst ([Item FilePath] -> Compiler [Item FilePath])
-> Compiler [Item FilePath] -> Compiler [Item FilePath]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
                    Pattern -> FilePath -> Compiler [Item FilePath]
forall a.
(Binary a, Typeable a) =>
Pattern -> FilePath -> Compiler [Item a]
loadAllSnapshots Pattern
ep FilePath
cs
                let ctx :: Context FilePath
ctx = [Context FilePath] -> Context FilePath
forall a. Monoid a => [a] -> a
mconcat [
                        FilePath
-> Context FilePath -> Compiler [Item FilePath] -> Context FilePath
forall a b. FilePath -> Context a -> Compiler [Item a] -> Context b
listField FilePath
"recent-posts" Context FilePath
pCtxForFooter ([Item FilePath] -> Compiler [Item FilePath]
forall a. a -> Compiler a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Item FilePath]
recent)
                      , FilePath
-> YearlyArchives
-> MonthlyArchives
-> Maybe FilePath
-> Context FilePath
forall a.
FilePath
-> YearlyArchives -> MonthlyArchives -> Maybe FilePath -> Context a
yearMonthArchiveField FilePath
"archives" YearlyArchives
y MonthlyArchives
m Maybe FilePath
year
                      , Context FilePath
footerCtx
                      ]
                FilePath -> Compiler (Item FilePath)
forall a. a -> Compiler (Item a)
makeItem FilePath
forall a. Monoid a => a
mempty
                    Compiler (Item FilePath)
-> (Item FilePath -> Compiler (Item FilePath))
-> Compiler (Item FilePath)
forall a b. Compiler a -> (a -> Compiler b) -> Compiler b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Identifier
-> Context FilePath -> Item FilePath -> Compiler (Item FilePath)
forall a.
Identifier -> Context a -> Item a -> Compiler (Item FilePath)
loadAndApplyTemplate (FilePath -> Identifier
fromFilePath (FilePath -> Identifier) -> FilePath -> Identifier
forall a b. (a -> b) -> a -> b
$ FilePath
tmBlogRoot FilePath -> FilePath -> FilePath
</> FilePath
"footer.html") Context FilePath
ctx
                    Compiler (Item FilePath)
-> (Item FilePath -> Compiler (Item FilePath))
-> Compiler (Item FilePath)
forall a b. Compiler a -> (a -> Compiler b) -> Compiler b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Item FilePath -> Compiler (Item FilePath)
relativizeUrls