import plac
import subprocess
import pandas as pd
import time
from datetime import datetime
from pathlib import Path
from shutil import copy2
import config
import psutil
import json

cfg = config.config()
report_dir = cfg.portal_dir + '\\System\\Report'
publish_dir = cfg.portal_dir + '\\Publish\\daten'
if not Path(publish_dir).exists():
    publish_dir = cfg.portal_dir + '\\daten'


@plac.pos('config_file', '', type=str)
def portal(config_file='GAPS_neu'):
    print(f"== Portal '{config_file}.xml' ==")
    full_filename = f'{cfg.xml_dir}\\{config_file}.xml'
    if not Path(full_filename).exists():
        print(f"!! Datei '{full_filename}' existiert nicht !!")
        return
    prepare_report_temp(config_file)
    pub_dir = Path(f'{publish_dir}\\{config_file}')
    rep_dir = f'{report_dir}\\{config_file}'
    if not pub_dir.exists():
        pub_dir.mkdir()

    for export_format in ['jpg', 'xls', 'pdf']:
        export_files(config_file, export_format, f'{rep_dir}\\{export_format}', pub_dir, f'{cfg.log_dir}\\{config_file}_{export_format}.mac.log')


def export_files(config_file, export_format, rep_dir, pub_dir, logfile):
    cmd = f'"{cfg.cognos_dir}\\runmac32.exe" "{cfg.tools_dir}\\publish-reports.mac" "{rep_dir}","{export_format}","{pub_dir}"'
    setup = {
        'start': datetime.now().timestamp(),
        'call': ['export_files', export_format, rep_dir, str(pub_dir), logfile],
        'description': f"Exportiere '{rep_dir}' nach '{pub_dir}'...",
        'cleanup': []
    }
    with open(logfile, 'w') as stream:
        p = subprocess.Popen(cmd, stdout=stream, stderr=stream)
        setup['pid'] = p.pid

    setup['reports'] = [f.name for f in sorted(Path(rep_dir).glob('*.pp[rx]'))]
    setup['exports'] = [str(translate_filename(f, export_format, str(pub_dir))) for f in setup['reports']]
    setup['exports_remaining'] = setup['exports']
    if export_format == 'jpg':
        setup['cleanup'].append(['rename_files', str(pub_dir)])
        setup['cleanup'].append(['cleanup_dir', str(pub_dir)])
    with open(f'{cfg.log_dir}\\running\\portal_{config_file}_{export_format}.json', 'w') as f:
        json.dump(setup, f, indent=2)


def observe(filename):
    with open(filename, 'r') as f:
        setup = json.load(f)

    while psutil.pid_exists(setup['pid']):
        setup['exports_remaining'] = [f for f in setup['exports_remaining'] if not Path(f).exists() or Path(f).stat().st_mtime < setup['start']]
        print('Fortschritt: ' + str(len(setup['exports']) - len(setup['exports_remaining'])) + '/' + str(len(setup['exports'])) + '...', end='\r')
        time.sleep(5)

    print('Abgeschlossen.             ')


def translate_filename(filename, export_format, pub_dir):
    if export_format == 'jpg':
        return Path(pub_dir + '\\' + filename[:-4] + 'graph1.jpg')
    return Path(pub_dir + '\\' + filename[:-4] + '_0.' + export_format)


def rename_files(pub_dir):
    for f in pub_dir.glob('*.jpg'):
        if f.exists():
            new_name = str(f).replace('graph', '_')
            f.replace(Path(new_name))


def cleanup_dir(pub_dir):
    for f in pub_dir.glob('*.htm'):
        f.unlink()


def prepare_report_temp(config_file):
    df = pd.read_csv(cfg.xml_dir + '\\info\\reports.csv', sep=';')
    df = df[df['Datei'].str.contains(config_file + '\\.', case=False)]
    format_list = [('GIF', 'jpg'), ('PDF', 'pdf'), ('XLS', 'xls')]

    for (filter_col, export_format) in format_list:
        reports = set(df[df[filter_col] == 'J']['Report'].to_list())
        rep_dir = f'{report_dir}\\{config_file}\\{export_format}'
        unlink_and_recreate(Path(rep_dir))

        for rep in reports:
            ppx = f"{report_dir}\\{rep}.ppx"
            ppr = f"{report_dir}\\{rep}.ppr"
            if Path(ppx).exists():
                copy2(ppx, rep_dir)
            elif Path(ppr).exists():
                copy2(ppr, rep_dir)


def unlink_and_recreate(dirname):
    if not dirname.exists():
        dirname.mkdir(parents=True)
    else:
        for f in dirname.glob('*.pp[xr]'):
            f.unlink()


if __name__ == '__main__':
    # plac.call(portal)
    portal()
    while True:
        time.sleep(60)