{-# OPTIONS_GHC -fno-warn-orphans #-}

{-# LANGUAGE FlexibleInstances   #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}

module Hledger.Web.Handler.MiscR
  ( getVersionR
  , getAccountnamesR
  , getTransactionsR
  , getPricesR
  , getCommoditiesR
  , getAccountsR
  , getAccounttransactionsR
  , getDownloadR
  , getFaviconR
  , getManageR
  , getRobotsR
  , getRootR
  , getOpenApiR
  ) where

import qualified Data.Map as M
import qualified Data.Text as T
import qualified Data.Yaml as Yaml
import qualified Data.ByteString as BS
import Yesod.Default.Handlers (getFaviconR, getRobotsR)

import Hledger
import Hledger.Web.Import
import Hledger.Web.WebOptions (packageversion)
import Hledger.Web.Widget.Common (journalFile404)

getRootR :: Handler Html
getRootR :: Handler Html
getRootR = do
  Handler ()
checkServerSideUiEnabled
  Route App -> Handler Html
forall (m :: * -> *) url a.
(MonadHandler m, RedirectUrl (HandlerSite m) url) =>
url -> m a
redirect Route App
JournalR

getManageR :: Handler Html
getManageR :: Handler Html
getManageR = do
  Handler ()
checkServerSideUiEnabled
  VD{j} <- Handler ViewData
getViewData
  require EditPermission
  defaultLayout $ do
    setTitle "Edit journal"
    $(widgetFile "manage")

getDownloadR :: FilePath -> Handler TypedContent
getDownloadR :: PackageVersionString -> Handler TypedContent
getDownloadR PackageVersionString
f = do
  Handler ()
checkServerSideUiEnabled
  VD{j} <- Handler ViewData
getViewData
  require EditPermission
  (f', txt) <- journalFile404 f j
  addHeader "Content-Disposition" ("attachment; filename=\"" <> T.pack f' <> "\"")
  sendResponse ("text/plain" :: ByteString, toContent txt)

-- hledger-web equivalents of the old hledger-api's handlers

getVersionR :: Handler TypedContent
getVersionR :: Handler TypedContent
getVersionR = do
  Permission -> Handler ()
require Permission
ViewPermission
  Writer (Endo [ProvidedRep (HandlerFor App)]) ()
-> Handler TypedContent
forall (m :: * -> *).
MonadHandler m =>
Writer (Endo [ProvidedRep m]) () -> m TypedContent
selectRep (Writer (Endo [ProvidedRep (HandlerFor App)]) ()
 -> Handler TypedContent)
-> Writer (Endo [ProvidedRep (HandlerFor App)]) ()
-> Handler TypedContent
forall a b. (a -> b) -> a -> b
$ PackageVersionString
-> Writer (Endo [ProvidedRep (HandlerFor App)]) ()
forall (m :: * -> *) a.
(Monad m, ToJSON a) =>
a -> Writer (Endo [ProvidedRep m]) ()
provideJson (PackageVersionString
 -> Writer (Endo [ProvidedRep (HandlerFor App)]) ())
-> PackageVersionString
-> Writer (Endo [ProvidedRep (HandlerFor App)]) ()
forall a b. (a -> b) -> a -> b
$ PackageVersionString
packageversion

getAccountnamesR :: Handler TypedContent
getAccountnamesR :: Handler TypedContent
getAccountnamesR = do
  VD{j} <- Handler ViewData
getViewData
  require ViewPermission
  selectRep $ provideJson $ journalAccountNames j

getTransactionsR :: Handler TypedContent
getTransactionsR :: Handler TypedContent
getTransactionsR = do
  VD{j} <- Handler ViewData
getViewData
  require ViewPermission
  selectRep $ provideJson $ jtxns j

getPricesR :: Handler TypedContent
getPricesR :: Handler TypedContent
getPricesR = do
  VD{j} <- Handler ViewData
getViewData
  require ViewPermission
  selectRep $
    provideJson $ map priceDirectiveToMarketPrice $ jpricedirectives j

getCommoditiesR :: Handler TypedContent
getCommoditiesR :: Handler TypedContent
getCommoditiesR = do
  VD{j} <- Handler ViewData
getViewData
  require ViewPermission
  selectRep $ do
    provideJson $ (M.keys . jinferredcommoditystyles) j

getAccountsR :: Handler TypedContent
getAccountsR :: Handler TypedContent
getAccountsR = do
  VD{j} <- Handler ViewData
getViewData
  require ViewPermission
  selectRep $ do
    provideJson $
      styleAmounts (journalCommodityStylesWith HardRounding j) $
      flattenAccounts $ mapAccounts (accountSetDeclarationInfo j) $ ledgerRootAccount $ ledgerFromJournal Any j

getAccounttransactionsR :: Text -> Handler TypedContent
getAccounttransactionsR :: Text -> Handler TypedContent
getAccounttransactionsR Text
a = do
  VD{j} <- Handler ViewData
getViewData
  require ViewPermission
  let
    rspec = ReportSpec
defreportspec
    thisacctq = Regexp -> Query
Acct (Regexp -> Query) -> Regexp -> Query
forall a b. (a -> b) -> a -> b
$ Text -> Regexp
accountNameToAccountRegex Text
a -- includes subs
  selectRep $ do
    provideJson $
      styleAmounts (journalCommodityStylesWith HardRounding j) $
      accountTransactionsReport rspec{_rsQuery=Any} j thisacctq

openApiYaml :: BS.ByteString
openApiYaml :: ByteString
openApiYaml = $(embedFileRelative "config/openapi.yaml")

getOpenApiR :: Handler Value
getOpenApiR :: Handler Value
getOpenApiR =
  case ByteString -> Either ParseException Value
forall a. FromJSON a => ByteString -> Either ParseException a
Yaml.decodeEither' ByteString
openApiYaml of
    Left ParseException
_ -> Handler Value
forall (m :: * -> *) a. MonadHandler m => m a
notFound
    Right Value
openapi -> do
      Text -> Text -> Handler ()
forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
addHeader Text
"Content-Type" Text
"application/json"
      Value -> Handler Value
forall a. a -> HandlerFor App a
forall (m :: * -> *) a. Monad m => a -> m a
return Value
openapi