#!/usr/bin/env stack
--  stack runghc --package hledger
-------------------------------------------------------------------------------
-- About this script. You can remove this text. See also hledger-script-example-short.hs.
--
-- This is an example of a hledger addon command (an executable named hledger-*),
-- implemented as a haskell script which can use hledger's API.
-- Save it as a different name, give it execute permission, and customise it.
--
-- This script is run by stack. You can use any of the commands below:
--
-- The `stack runghc` command runs within a hledger source tree, using that local hledger version.
-- It installs haskell packages and GHC if needed, from the stackage snapshot configured in the stack.yaml file.
--  stack runghc --package hledger
--
-- The `stack script` command installs known hledger, haskell package and GHC versions from a specified stackage snapshot.
-- This is the most robust setup. --verbosity=info shows install progress. --compile makes a standalone binary.
--  stack script --snapshot lts-23.0                     --verbosity=error --package hledger
--  stack script --snapshot nightly-2024-12-16 --compile --verbosity=error --package hledger
--
-- Or the script can be run by cabal, which installs packages if needed (but not GHC).
--  #!/usr/bin/env cabal
--  {- cabal:
--  build-depends: base, directory, text, hledger
--  -}
--
-- If compiled to a binary, the script will run without stack or cabal or haskell packages.
-- (It will still require certain C libraries.)
-------------------------------------------------------------------------------
{-

script-example - my new script

-}

-- Haskell language customisations. OverloadedStrings is a useful one.
-- https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/intro.html
{-# LANGUAGE OverloadedStrings #-}

-- Import things from haskell packages - the ones specified above, or included with the GHC specified above,
-- eg https://downloads.haskell.org/ghc/latest/docs/users_guide/9.10.1-notes.html#included-libraries
-- This provides most of hledger's API that's useful for scripts.
import Hledger.Cli.Script
-- Haskell has a built-in String type; hledger also uses the more efficient Text type.
import qualified Data.Text as T
import qualified Data.Text.IO as T

-- If you use hledgerCommandMode, and getHledgerCliOpts below, your script will
-- support -h/--help, -f/--file and other common hledger options.
cmdmode = hledgerCommandMode (unlines
    ---------------------------standard terminal width-----------------------------
    -- command name on first line:
  ["script-example"
    -- then --help text:
  ,"Usage: hledger-script-example [OPTS] [ARGS]"
  ,"or:    hledger script-example -- [OPTS] [ARGS]"
  ,"Examples:"
  ,"$ hledger-script-example         # do the thing"
  ,"$ hledger-script-example --help  # print help"
  ])
    -- you can add or change options here (see CliOptions.hs); usually not needed
  [] [generalflagsgroup1] [] ([], Just $ argsFlag "[ARGS]")

-- Most scripts have three steps:
-- 1. process command line options/arguments
-- 2. read the journal file
-- 3. do something with it.
main = do
  opts@CliOpts{reportspec_=rspec} <- getHledgerCliOpts cmdmode
  withJournalDo opts $ \j -> do
    putStrLn "hello"



-------------------------------------------------------------------------------
{-
Script code examples. You can remove this text.

See also: bin/*.hs

Show a count of transactions, possibly filtered by a query:

    d <- getCurrentDay
    let
      q = _rsQuery rspec
      ts = filter (q `matchesTransaction`) $ jtxns $ journalApplyValuationFromOpts rspec j
    printf "File %s: %d transactions\n" (journalFilePath j) (length ts)

Run a postings report (like hledger register) and print the posting(s) with highest amount
(like hledger-register-max.hs):

    let
      postingReportItems = postingsReport rspec j
      maxbal = fifth5 $ maximumBy (comparing fifth5) r
      is = filter ((== maxbal).fifth5) r
    mapM_ printItem is

    printItem (_, _, _, p, bal) = do
      let
        d      = postingDate p
        mt     = ptransaction p
        desc   = fmt  30 $ maybe "-" tdescription mt
        acct   = fmt  30 $ paccount p
        amt    = fmta 12 $ T.pack $ showMixedAmountOneLine $ pamount p
        baltxt = fmta 12 $ T.pack $ showMixedAmountOneLine bal
      T.putStrLn $ T.unwords [showDate d, desc, "", acct, "", amt, " ", baltxt]
      where
        fmt w  = formatText True (Just w) (Just w) . textElideRight w
    fmta w = formatText False (Just w) Nothing

Use the [s|...|] multiline string syntax (requires --package string-qq and {-# LANGUAGE QuasiQuotes #-}):

    cmdmode = hledgerCommandMode (unlines
        -- Command name, then --help text. Note, empty help lines get stripped.
    [s| script-example
    This is an example of a (hledger-lib-using) hledger script."
    Usage: hledger-script-example [OPTS] [ARGS]"
    or:    hledger script-example -- [OPTS] [ARGS]"
    Save it under another name and customise it."
    The hledger- name makes it appear in hledger's commands list."
    Examples:"
    $ hledger-script-example --help"
    (this help)"
      |]
        ------------------------------------78----------------------------------------
      [] [generalflagsgroup1] [] ([], Just $ argsFlag "[ARGS]")  -- or Nothing

-}
