{- | The entry point of the application.

    It reads the /config.yaml/ file into memory before doing anything else.
    After that it access the page data of the selected page, either from cache
    or from the Wiki Table based on the command line arguments used.

    When the page data is fetched it starts the 'Table' generation by calling
    the @'parseTable'@ function and later loops over the different 'Lang'uages
    found in the /config.yaml/ page configuration section and renders a
    different page body for each of the languages.
-}
main :: IO ()
main = do
    putStrLn ("============================================================\n" ++
              " Running Application\n" ++
              "============================================================\n" ++
              " * Decoding config.yaml")
    Yaml.decodeFileEither "config.yaml" >>= either (error . show) (runReaderT go)
  where
    go = do
        Config{..} <- ask
        forM_ pages $ \pc@PageConf{..} -> do
            liftIO $ putStrLn (" * Reading data from Wiki page ID: " ++ pageId)
            pageData <- getData pageId
            case pageData of
                Nothing -> liftIO $ putStrLn "!!! Warning: failed to fetch doc, not updating the listings..."
                Just pageData' -> do
                    table <- parseTable pageData'
                    forM_ languages $ \lang -> do
                        liftIO $ putStrLn (" *     Language: " ++ show lang)
                        renderTable rootDir lang pc table


-- =============================================================================
-- * Types
-- =============================================================================


{- | Creates a monad that handles the assignment of the @Config@ type. It uses
	the functionality of both the @Reader@ monad and the @IO@ monad.

	@ReaderT@ monad transformer
	@Config@ the return value of @ask@ function
	@IO@ monad on which the @Reader@ acts.

	By using this monad, one can read all values of type @Config@ and perform
	IO actions.
-}
main :: IO ()
main = do
    putStrLn ("============================================================\n" ++
              " Running Application\n" ++
              "============================================================\n" ++
              " * Decoding config.yaml")
    Yaml.decodeFileEither "config.yaml" >>= either (error . show) (runReaderT go)
  where
    go = do
        Config{..} <- ask
        forM_ pages $ \pc@PageConf{..} -> do
            liftIO $ putStrLn (" * Reading data from Wiki page ID: " ++ pageId)
            pageData <- getData pageId
            case pageData of
                Nothing -> liftIO $ putStrLn "!!! Warning: failed to fetch doc, not updating the listings..."
                Just pageData' -> do
                    table <- parseTable pageData'
                    forM_ languages $ \lang -> do
                        liftIO $ putStrLn (" *     Language: " ++ show lang)
                        renderTable rootDir lang pc table


-- =============================================================================
-- * Types
-- =============================================================================


{- | Creates a monad that handles the assignment of the @Config@ type. It uses
	the functionality of both the @Reader@ monad and the @IO@ monad.

	@ReaderT@ monad transformer
	@Config@ the return value of @ask@ function
	@IO@ monad on which the @Reader@ acts.

	By using this monad, one can read all values of type @Config@ and perform
	IO actions.
-}
main = do
    putStrLn ("============================================================\n" ++
              " Running Application\n" ++
              "============================================================\n" ++
              " * Decoding config.yaml")
    Yaml.decodeFileEither "config.yaml" >>= either (error . show) (runReaderT go)
  where
    go = do
        Config{..} <- ask
        forM_ pages $ \pc@PageConf{..} -> do
            liftIO $ putStrLn (" * Reading data from Wiki page ID: " ++ pageId)
            pageData <- getData pageId
            case pageData of
                Nothing -> liftIO $ putStrLn "!!! Warning: failed to fetch doc, not updating the listings..."
                Just pageData' -> do
                    table <- parseTable pageData'
                    forM_ languages $ \lang -> do
                        liftIO $ putStrLn (" *     Language: " ++ show lang)
                        renderTable rootDir lang pc table


-- =============================================================================
-- * Types
-- =============================================================================


{- | Creates a monad that handles the assignment of the @Config@ type. It uses
	the functionality of both the @Reader@ monad and the @IO@ monad.

	@ReaderT@ monad transformer
	@Config@ the return value of @ask@ function
	@IO@ monad on which the @Reader@ acts.

	By using this monad, one can read all values of type @Config@ and perform
	IO actions.
-}