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.*/'
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(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}


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(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()
