#!/usr/bin/env ysh                                               # -*- sh -*-
# Tested with ysh 0.24
# https://oils.pub/release/latest/doc/ysh-tour.html
#  https://oils.pub/release/latest/doc/ref/
# Tested with jj 0.26 with auto-track disabled, ie in ~/.jjconfig.toml:
#  [snapshot]
#  auto-track = "none()"

const HELP = '''
-------------------------------------------------------------------------------
hledger-jj [COMMAND [OPTS]] - easy version control for hledger journals

An easy CLI for keeping your data in version control, using jj and a git repo.
Works for $LEDGER_FILE and its subfiles only (-f is not yet supported).
A repo will be created if needed, in $LEDGER_FILE's directory.
You can run this tool from any directory. Commands may be abbreviated.
Options are passed to jj; you may need to write -- first.
''' #'

const HELP2 = '''

Examples:
$ hledger jj status
$ hledger jj diff
$ hledger jj commit
$ hledger jj c "new txns"
$ hledger jj log -- -n5
$ hledger-jj l -n5 --stat
'''

# You could install this as more convenient top level hledger commands by
# making hledger-commit, hledger-diff, hledger-status, hledger-log scripts like
#
# #!/bin/sh
# #hledger-commit
# hledger-jj commit "$@"

const S = /%start/
const E = /%end/
# const WS = /%word_start/
# const WE = /%word_end/
const FILE1 = ENV.LEDGER_FILE
const DIR   = $(dirname "$FILE1")
const FILES = split( $(hledger -f "$FILE1" files) => replace(/ DIR '/' /, '') )

proc help() {
  write -n -- """
$HELP
Commands:
"""
  # grep -E '^(proc +)?\w.*\(\) *{ *#+' "$0" | sed -E -e 's/^proc +//' -e 's/\(\) *\{//' -e 's/#+ /\t /'
  redir < $0 {
    for l in (io.stdin) {
      if (l ~ /S ('proc' space+)? <capture w dot* as name> '(' (![')'])* ')' dot* '###' space* <capture dot* as help>/) {
        echo "$[_group('name')]	$[_group('help')]"
      }
    }
  }
  write -n $HELP2
}

proc setup() { # do initial checks/setup
  check_jj
  ensure_journal_repo
}

proc check_jj() { # check that jj is installed
  if ! hash jj 2>/dev/null {
    write -n >&2 '''
This command requires jj, but it is not installed in $PATH.
Please install it and try again. https://jj-vcs.github.io
'''
    exit 1
  }
}

proc ensure_journal_repo() { # ensure that the journal file has a jj/git repo
  cd "$DIR" {
    if ! jj status >/dev/null 2>&1 {
      jj git init --colocate
      write "Created new colocated jj/git repo in $DIR"
    }
  }
}

proc status(...opts) { ### [OPTS] - show status of journal files
  cd "$DIR" { jj status --color=always @opts @FILES | grep -vE '^Untracked paths:|\?' }
}

proc diff(...opts) { ### [OPTS] - show unrecorded changes in journal files
  cd "$DIR" { jj diff @opts @FILES }
}

proc commit(...opts) { ### [MSG [OPTS]] - record changes to journal files
  cd "$DIR" {
    jj file track @FILES
    var msg=${2:-$(date +'%Y-%m-%d %H:%M')}
    # if [ $# -ge 1 ]; then
    #     shift
    # fi
    # shift
    jj commit -m "$msg" @opts @FILES   #"$@"
  }
}

proc log(...opts) { ### [OPTS] - list recorded changes to journal files
  cd "$DIR" { jj log @opts @FILES }
}

if (len(ARGV) < 1) {
  help
} else {
  var args = ARGV[1:]
  case (ARGV[0]) {
    /S ('h'('e'('l'('p')?)?)? | '-h' | '-'? '-help') E/ { help }
    /S 's'('t'('a'('t'('u'('s')?)?)?)?)? E/ { setup; status @args }
    /S 'd'('i'('f'('f')?)?)? E/             { setup; diff @args }
    /S 'c'('o'('m'('m'('i'('t')?)?)?)?)? E/ { setup; commit @args }
    /S 'l'('o'('g')?) ?E/                   { setup; log @args }
    (else)                                  { echo "Unknown command: $[ARGV[0]]"; return 1 }
  }
}
