#!/usr/bin/env python3
# An example of using Python to convert a certain CSV to hledger journal entries.
# This won't work as-is (unless you have this particular kind of CSV);
# use it for inspiration. hledger's own CSV rules are not used at all here.


__version__ = "1.0"
__author__ = "Simon Michael"

VERSION = "%prog " + __version__
USAGE = """%prog [options] [CSVFILE [JOURNALFILE]]
Reads a [certain kind of] CSV, writes a hledger journal.
Journal entries will be in the same order as the CSV records.

Requirements: python 3.
"""

# from pprint import pprint as pp
import csv
import datetime
import optparse
import re
import subprocess
import sys
import tempfile
# import warnings

def parse_options():
    parser = optparse.OptionParser(usage=USAGE, version=VERSION)
    opts, args = parser.parse_args()
    if len(args) > 2:
        parser.print_help()
        sys.exit()
    return opts, args

def single_space(ms):
    if ms is not None: ms = re.sub(r'  +',' ',ms)
    return ms

# Join two strings with the give separator, but omit the separator
# if either string is empty.
def intercalate2(sep,astr,bstr):
    if astr and bstr:
        return astr + sep + bstr
    else:
        return astr + bstr

def main():
    opts, args = parse_options()
    out = open(args[1],'w') if len(args) > 1 else sys.stdout
    with open(args[0],'r') if len(args) > 0 else sys.stdin as csvfile:

        # Process CSV records, and generate a hledger journal entry for each transaction.

        for r in csv.reader(csvfile):

            # skip headings (record containing no numbers)
            if all(map(lambda v: not any(c.isdigit() for c in v), r)): continue

            # hledger doesn't like records with only one field
            if len(r) < 2: continue

            # skip non-transaction records
            if re.match(r'^(Starting Balance|Net Change|Total|)$',r[0]): continue
            
            # write a hledger journal entry
            property_,date_,payee_payer_,type_,reference_,debit_,credit_,balance_,description_,gl_account_ = r
            date         = datetime.datetime.strptime(date_,"%m/%d/%Y").date().isoformat()
            code         = f" ({reference_})" if reference_ else ""
            description  = intercalate2(' | ', payee_payer_, intercalate2(' ', description_, type_))
            amount1      = f"${debit_}" if debit_ else ""
            amount2      = f"${credit_}" if credit_ else ""
            balance1     = balance_
            account1     = f"Properties:{property_}"
            if gl_account_[0].isdigit():
                account2 = f"{gl_account_[0]}xxx:{gl_account_}"
            else:
                account2 = f"{gl_account_}"
            account1, account2 = single_space(account1), single_space(account2)
            out.write(f"""\
{date}{code} {description}
    {account1}    {amount1} ; = {balance1}
    {account2}    {amount2}

""")

if __name__ == "__main__": main()
