import csv
from pathlib import Path
from itertools import chain


class IFTConverter:
    def __init__(self, base_dir):
        self.config = {
            '_A_': {
                '1': self.import_config(base_dir + 'actuals_header.txt'),
                '2': self.import_config(base_dir + 'actuals_item.txt')
            },
            '_B_': {
                '010': self.import_config(base_dir + 'budget_line.txt')                
            },
            '_C_': {
                '010': self.import_config(base_dir + 'commitment_line.txt')
            },
            '_K_': {
                '1': self.import_config(base_dir + 'controllingdoc_header.txt'),
                '2': self.import_config(base_dir + 'controllingdoc_item.txt')
            },
            '_P_': {
                '010': self.import_config(base_dir + 'plan_line.txt')
            }
        }

    def import_config(self, filename):
        with open(filename, 'r') as frh:

            return [(int(line['start']) - 1, int(line['start']) + int(line['length']) - 1)
                    for line in csv.DictReader(frh, delimiter='\t')]

    def convert_dir(self, path):
        source_path = Path(path)
        target_path = source_path.parent.joinpath('prod_csv')

        for filename in source_path.glob('*.txt'):
            print(filename.name)
            self.convert_file(filename, target_path)

    def convert_file(self, source, target_path):
        cfg = self.conversion_config(source.name)
        target = target_path.joinpath(source.name[:-4] + '.csv')

        content = {}
        last_key = list(cfg.keys())[-1]

        with open(source, 'r', errors='ignore') as frh:
            with open(target, 'w') as fwh:
                for line in frh.readlines():
                    for key, rules in cfg.items():
                        if line.startswith(key):
                            content[key] = self.convert_line(line, rules)
                            break
                    if line.startswith(last_key):
                        fwh.write('\t'.join(chain(*content.values())) + '\n')

    def convert_line(self, line, rules):
        return [line[rule[0]:rule[1]].strip() for rule in rules]

    def conversion_config(self, filename):
        for key, cfg in self.config.items():
            if key in filename:
                return cfg
        return {
            '0': []
        }


def main():
    ift_conv = IFTConverter('/home/robert/projekte/python/dbtools/config/IFT/')
    ift_conv.convert_dir('/home/robert/projekte/python/BMW_Wien/IFT/prod')


if __name__ == '__main__':
    main()