from pathlib import Path
import shutil
from xml.etree import ElementTree as et
import pandas as pd
import matplotlib.pyplot as plt

from run_simstadt_workflow import find_simstadt, SCRIPT_DIR, run_workflow

import logging
logging.getLogger().setLevel(logging.WARN)

#######################################################################
# User params
SIMSTADT2_GLOB = 'Desktop/SimStadt2_0.*/'
# Check env variable?
REPO_PATH = Path.home() / 'git' / 'simstadt2' / 'TestRepository'
PROJECT_NAME = 'Gruenbuehl'
CITYGML = 'Gruenbuehl_LOD2_ALKIS_1010.gml'
SURFACES = ['outWalls', 'pitchedRoof']
WINDOW_RATIOS = [0, 0.5, 1]
# Heat demand, with custom BuildingPhysics
TEMPLATE_NAME = '99_HeatDemand'
#######################################################################

#######################################################################
XML_LIB_URL = 'http://www.simstadt.eu/BuildingPhysicsLibraries'
NAMESPACE = {'': XML_LIB_URL}
PROJECT_PATH = REPO_PATH / f'{PROJECT_NAME}.proj'
PARAMS = 'params.xml'
BUILDING_PHYSICS_LIBRARY = 'GermanBuildingTypologyLibrary_IWU.xml'
#######################################################################


def copy_workflow_from_template(template_name, project_path):
    template = SCRIPT_DIR / 'Template' / f'{template_name}.flow'
    workflow_path = project_path / f'{template_name}.flow'

    shutil.copytree(template, workflow_path, dirs_exist_ok=True)

    physics_processor_step = workflow_path / '01_Preprocessing.step/02_PhysicsPreprocessor.step'
    return workflow_path, physics_processor_step


def set_custom_library(physics_processor_step):
    custom_library_path = physics_processor_step / BUILDING_PHYSICS_LIBRARY

    physics_processor_params = physics_processor_step / PARAMS

    param_tree = et.parse(physics_processor_params)
    root = param_tree.getroot()

    lib_node = root.find(
        ".//object[@class='de.hft.stuttgart.simstadt2.assessment.PhysicsXmlLib']/void[@property='path']/string")
    lib_node.text = str(custom_library_path)
    param_tree.write(physics_processor_params)
    return custom_library_path

##########################################################


def parse_library(library_path: Path) -> et.ElementTree:
    et.register_namespace('', XML_LIB_URL)
    return et.parse(library_path)


def set_custom_window_ratio(window_ratio: float, tree: et.ElementTree, window_ratio_node: float, export_path: Path):
    root = tree.getroot()
    root.find('name', NAMESPACE).text = f"Custom Physics Library with Window Ratio : {window_ratio}"
    for surface in SURFACES:
        for node in root.findall(f'.//{surface}', NAMESPACE):
            window_ratio_node = node.find('./windowRatio', NAMESPACE)
            if window_ratio_node is not None:
                window_ratio_node.text = str(window_ratio)
    tree.write(export_path)


def parse_results(window_ratio, heat_demand_csv):
    df = pd.read_csv(heat_demand_csv,
                     skiprows=list(range(19)) + [20],
                     sep=';',
                     decimal=','
                     )

    heating_demand_MWh = df['Yearly Heating demand'].sum() / 1000
    cooling_demand_MWh = df['Yearly Cooling demand'].sum() / 1000
    print(f"Window Ratio : {window_ratio * 100} %")
    print(f"Total heating demand : {heating_demand_MWh:.0f} MWh / a")
    print(f"Total cooling demand : {cooling_demand_MWh:.0f} MWh / a")
    return {'WindowRatio': window_ratio,
            'HeatingDemand': heating_demand_MWh,
            'CoolingDemand': cooling_demand_MWh}


def main():
    workflow_path, physics_processor_step = copy_workflow_from_template(TEMPLATE_NAME, PROJECT_PATH)
    custom_library_path = set_custom_library(physics_processor_step)
    lib_tree = parse_library(custom_library_path)

    all_results = []
    for window_ratio in WINDOW_RATIOS:
        # TODO: Status quo too
        set_custom_window_ratio(window_ratio, lib_tree, window_ratio, custom_library_path)

        output_files = run_workflow(find_simstadt(SIMSTADT2_GLOB), workflow_path, [CITYGML])

        heat_demand_csv = next(file for file in output_files if 'HEATING_AND_COOLING.csv' in file.name)

        ################### Parse heat demand ########################

        all_results.append(parse_results(window_ratio, heat_demand_csv))

    df = pd.DataFrame(all_results).set_index('WindowRatio')
    print(df)
    df.plot()
    plt.ylabel('MWh')
    plt.title("Demands depending on Window Ratio")
    plt.show()


if __name__ == "__main__":
    main()
