{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
{-|

Embedded documentation files in various formats, and helpers for viewing them.

|-}

module Hledger.Cli.DocFiles (

   Topic
  ,docFiles
  ,docTopics
  ,lookupDocNroff
  ,lookupDocTxt
  ,lookupDocInfo
  ,printHelpForTopic
  ,runManForTopic
  ,runInfoForTopic

  ) where

import Prelude ()
import Prelude.Compat
import Data.FileEmbed
import Data.String
import System.IO
import System.IO.Temp
import System.Process

import Hledger.Utils (first3, second3, third3)

type Topic = String

docFiles :: IsString a => [(Topic, (a, a, a))]
docFiles = [
   ("cli",
    ($(makeRelativeToProject "doc/hledger.1" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/hledger.1.txt" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/hledger.1.info" >>= embedStringFile)
    ))
  ,("ui",
    ($(makeRelativeToProject "doc/other/hledger-ui.1" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger-ui.1.txt" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger-ui.1.info" >>= embedStringFile)
    ))
  ,("web",
    ($(makeRelativeToProject "doc/other/hledger-web.1" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger-web.1.txt" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger-web.1.info" >>= embedStringFile)
    ))
  ,("api",
    ($(makeRelativeToProject "doc/other/hledger-api.1" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger-api.1.txt" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger-api.1.info" >>= embedStringFile)
    ))
  ,("journal",
    ($(makeRelativeToProject "doc/other/hledger_journal.5" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger_journal.5.txt" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger_journal.5.info" >>= embedStringFile)
    ))
  ,("csv",
    ($(makeRelativeToProject "doc/other/hledger_csv.5" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger_csv.5.txt" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger_csv.5.info" >>= embedStringFile)
    ))
  ,("timeclock",
    ($(makeRelativeToProject "doc/other/hledger_timeclock.5" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger_timeclock.5.txt" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger_timeclock.5.info" >>= embedStringFile)
    ))
  ,("timedot",
    ($(makeRelativeToProject "doc/other/hledger_timedot.5" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger_timedot.5.txt" >>= embedStringFile)
    ,$(makeRelativeToProject "doc/other/hledger_timedot.5.info" >>= embedStringFile)
    ))
  ]

docTopics :: [Topic]
docTopics = map fst docFiles

lookupDocTxt :: IsString a => Topic -> a
lookupDocTxt name =
  maybe (fromString $ "No text manual found for topic: "++name) second3 $ lookup name docFiles

lookupDocNroff :: IsString a => Topic -> a
lookupDocNroff name =
  maybe (fromString $ "No man page found for topic: "++name) first3 $ lookup name docFiles

lookupDocInfo :: IsString a => Topic -> a
lookupDocInfo name =
  maybe (fromString $ "No info manual found for topic: "++name) third3 $ lookup name docFiles

printHelpForTopic :: Topic -> IO ()
printHelpForTopic t =
  putStrLn $ lookupDocTxt t

runManForTopic :: Topic -> IO ()
runManForTopic t =
  withSystemTempFile ("hledger-"++t++".nroff") $ \f h -> do
    hPutStrLn h $ lookupDocNroff t
    hClose h
     -- the temp file path will presumably have a slash in it, so man should read it
    callCommand $ "man " ++ f

runInfoForTopic :: Topic -> IO ()
runInfoForTopic t =
  withSystemTempFile ("hledger-"++t++".info") $ \f h -> do
    hPutStrLn h $ lookupDocInfo t
    hClose h
    callCommand $ "info " ++ f