from pathlib import Path
from docxtpl import DocxTemplate
from reportsjob import ReportJobError, get_valid_filename
import os
import json
import jinja2
import sys


def inject(jinja_env):
    this_file_path = Path(__file__)
    builtin_filters = str(this_file_path.parent.parent.joinpath("builtin_filters.py"))
    custom_filters = str(this_file_path.parent.parent.parent.joinpath("custom_filters.py"))

    for filters_file in [builtin_filters, custom_filters]:
        if not os.path.isfile(filters_file):
            raise Exception("Cannot find filters file: " + filters_file)
        with open(filters_file) as f:
            code = compile(f.read(), filters_file, 'exec')
            exec(code, globals(), locals())    
        custom_filters = locals()['get_filters'](jinja_env.globals)
        for filter_name, filter_code in custom_filters.items():
            jinja_env.filters[filter_name] = filter_code

        custom_functions = locals()['get_functions'](jinja_env.globals)
        for function_name, function_code in custom_functions.items():
            #jinja_env.filters[filter_name] = filter_code
            jinja_env.globals.update({function_name: function_code})


def run(docxtemplate: str, datafile: str, format: str, output: str) -> list:
    generated_file_list = []
    output_path = Path(output)
    os.makedirs(str(output_path), exist_ok=True)

    with open(datafile, 'r', encoding='utf8') as f:
        s = f.read()
    json_data = json.loads(s)
    if not 'items' in json_data:
        raise ReportJobError("Invalid JSON File [expected 'items' property]")

    if not 'meta' in json_data:
        raise ReportJobError("Invalid JSON File [expected 'meta' property]")

#    if not 'filename' in json_data['meta']:
#	    raise ReportJobError("Invalid JSON File [expected 'meta.filename' property]")

    meta = json_data['meta']

    jinja_env = jinja2.Environment()
    inject(jinja_env)

    for idx, item in enumerate(json_data['items']):
#        fname = json_data['meta']['filename']
#        fname = fname.format(**item)
#        fname = get_valid_filename(fname)
        report_page_data = {
            "meta": meta,
            "data": item
        }
        doc = DocxTemplate(docxtemplate)
        #jinja_env.filters['count'] = len
        doc.render(report_page_data, jinja_env)
        if isinstance(item, dict):
            prog = int(item.get('id', idx+1))			
        else:
            prog = idx
        fulloutputfilename = str(output_path.joinpath(str(prog) + '.docx'))			
        doc.save(fulloutputfilename)
        generated_file_list += [fulloutputfilename]

    return generated_file_list