"""
Convert's Text files to SCID files for SierraChart
It will create a new scid file for every text file it finds
  format is assumed to be D T O H L C V T with comma separated variables
It will continue to update the scid file every REFRESH seconds
  generally refresh would be set to 1/2 the time period for the text file updates
"""

import os
import struct
from time import sleep
from datetime import datetime as dt, timedelta as tdelta
import subprocess

# these are linux format, windows might need to use double backslashes \\
FILES_IN = "/home/john/Python/Trading/textfiles/"
FILES_OUT = "/home/john/zRamdisk/SierraData/"
TIMEZONE = 0  # scid saved as UTC, use this if the text file is another time zone
KEEP_UPDATING = True  # set to False to convert and stop; True for live updating
REFRESH = 0.25  # refresh every 1/4 second for 1/2 second updating text files
TEXT_FILE_SUFFIX = ".txt"  # usually .txt or .csv

sizeHeader = 0x38
sizeRecord = 0x28
file_header = (b'SCID8\x00\x00\x00\x28\x00\x00\x00\x01\x00\x00\x00\x00\x00' +
               b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +
               b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +
               b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')


def excel_date(datetime, offset=TIMEZONE):
    """convert date&time with offset in hours to excel format for scid"""
    delta = datetime - dt(1899, 12, 30) + tdelta(hours=offset)
    return delta.days + delta.seconds / 86400


def python_date(exceldt, offset=TIMEZONE):
    """convert date&time with offset in hours to python format"""
    excel_as_delta = tdelta(days=exceldt//1) + tdelta(seconds=exceldt%1*86400)
    return dt(1899, 12, 30) + excel_as_delta + tdelta(hours=offset)

def write_struct(record, f):
    if len(record) == 8 and record[0][0].isnumeric():
        out = [excel_date(dt.strptime(f'{record[0]} {record[1]}', '%Y-%m-%d %H:%M:%S.%f'))]
        out.extend([float(s) for s in record[2:]])
        # note that SC packs dt, O, H, L, C, T, V not V, T so swap them
        wt = struct.pack('d4f4I', out[0], out[1], out[2], out[3], out[4], int(out[6]), int(out[5]), 0, 0)
        f.write(wt)


def create_base(f):
    record = None
    with open(FILES_OUT + f[: -3] +'scid', "wb") as scidfile:
        scidfile.write(file_header)
        with open(FILES_IN + f, "r") as txtfile:
            for line in txtfile:
                record = line.split(',')
                write_struct(record, scidfile)
    return f'{record[0]} {record[1]}'  # will update when date+time changes


def update_if_changed(files):
    for f in files:
        with open(FILES_IN + f, "r") as txtfile:
            record = txtfile.readlines()[-1].split(',')
            last_dt = f'{record[0]} {record[1]}'
            if files[f] == last_dt:
                continue
            files[f] = last_dt
            with open(FILES_OUT + f[: -3] +'scid', "ab") as scidfile:
                write_struct(record, scidfile)


if __name__ == '__main__':
    files = sorted(k for k in os.listdir(path=FILES_IN) if k[-4:] == TEXT_FILE_SUFFIX)
    files = {k: '' for k in files}
    for f in files:
        files[f] = create_base(f)
    print('finished base')
    if KEEP_UPDATING:
        # now test each input file each REFRESH interval & update if datetime changed
        while True:
            sleep(REFRESH)
            update_if_changed(files)

