import requests
import os
import subprocess
import time
import psutil
import argparse
import macros_generator as mg


STARCCM_PATH = '/home/user/Siemens/19.02.009-R8/STAR-CCM+19.02.009-R8/star/bin/starccm+'
NUMBER_PROCESSES = 16


def download_file_from_fastapi(api_url, params, full_file_name):
    response = requests.post(api_url, json=params)

    if response.status_code == 200:
        with open(full_file_name, "wb") as f:
            f.write(response.content)
        print("File downloaded successfully.")
    else:
        print(f"Failed to download file. Status code: {response.status_code}")


def terminate_process_by_name(process_name):
    # Проходим по всем процессам в системе
    for proc in psutil.process_iter(['pid', 'name']):
        try:
            # Если имя процесса совпадает с искомым
            if proc.info['name'] == process_name:
                # Завершаем процесс
                proc.terminate()
                print(f"Процесс '{process_name}' с PID {proc.pid} был завершен.")
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess) as e:
            print(f"Не удалось завершить процесс '{process_name}': {e}")


def create_directory(path):
    if not os.path.exists(path):
        os.makedirs(path)


def delete_directory(path):
    if os.path.exists(path):
        os.remove(path)


def run_macros(macros_name, model_name=None, new_model=False, is_gpgpu=False):

    np_value = '1 -gpgpu auto' if is_gpgpu else str(NUMBER_PROCESSES)

    if new_model:
        macros_command = f'{STARCCM_PATH} -np {np_value} -new -batch \'{macros_name}\''
    else:
        if model_name is None:
            raise ValueError("model_name must be provided if new_model is False")
        macros_command = f'{STARCCM_PATH} -np {np_value} \'{model_name}\' -batch \'{macros_name}\''

    subprocess.run(
        ["bash", "-c", macros_command])


def run_experiment(angle):

    chemkin_path = "/media/user/Новый том/burner_automation/burner_data/chemkin"
    mesh_base_size = 0.7
    cpu_stopping_criterion = 200
    stopping_criterion = 7000

    main_path = '/media/user/Новый том/burner_automation/experiment_data'
    create_directory(main_path)

    diameters = {'d1': 1442, 'd2': 1016, 'd3': 640, 'd4': 325, 'd5': 325, 'd6': 245}

    default_values = {
        "N1": 24,
        "L1": 70.0,
        "a1": 60.0,
        "N2": 18,
        "L2": 105.0,
        "N3": 9,
        "L3": 30.0
    }

    # number_outer_blades = [12, 24, 36, 48]
    #number_outer_blades = 24.0
    # length_outer_blades = [44, 70, 86, 107.5]
    #length_outer_blades = 70.0
    # angle_outer_blades = [30.0, 45.0, 60.0, 75.0]
    # number_middle_blades = [9, 18, 27, 36]
    #number_middle_blades = 18.0
    # load = [190, 260, 315, 400, 465]
    # load_eco = [260, 315, 400, 465]
    load = 450
    # recycling_eco = [0, 7, 14, 21, 28]
    # recycling = [0, 5, 10, 15, 20, 25, 30]
    # recycling = [0, 6, 12, 18, 24, 30]
    recycling = 0

    start_time = time.time()

    directories_list = []

    api_url = "http://10.6.23.120:8000/api/v1/generate_geom"
    params = {
        "a1": angle
    }
    geometry_path = str(24) + '_' + str(70) + '_' + str(angle) + '_' + str(18)
    geometry_path_full = os.path.join(main_path, geometry_path, 'geometry')
    create_directory(geometry_path_full)

    geometry_file_name = os.path.join(geometry_path_full, 'geometry.stp')

    download_file_from_fastapi(api_url, params, geometry_file_name)

    macros_path = os.path.join(main_path, geometry_path, 'general_macros')
    directories_list.append(macros_path)

    MODEL_PATH = os.path.join(main_path, geometry_path, 'model')
    directories_list.append(MODEL_PATH)

    model_parameters = {
        'geometry_path': geometry_file_name,
        'chemkin_path': chemkin_path,
        'init_model_folder': MODEL_PATH,
        'bladeCount': 18,
        'mesh_base_size': mesh_base_size
        }

    fuel_parameters = mg.load_calculation(load, diameters)

    recycling_parameters = mg.recycling_calculation(fuel_parameters['alpha'], fuel_parameters['gas_consumption'],
                                                    fuel_parameters['air_consumption'], recycling)

    experiments_path = os.path.join(main_path, geometry_path, 'experiments')
    directories_list.append(experiments_path)

    load_path = os.path.join(experiments_path, str(load))
    directories_list.append(load_path)

    load_macros_experiment_path = os.path.join(load_path, 'macros')
    directories_list.append(load_macros_experiment_path)

    load_model_experiment_path = os.path.join(load_path, 'model')
    directories_list.append(load_model_experiment_path)

    recycling_experiment_path = os.path.join(load_path, str(recycling))
    directories_list.append(recycling_experiment_path)

    recycling_macros_experiment_path = os.path.join(recycling_experiment_path, 'macros')
    directories_list.append(recycling_macros_experiment_path)

    solver_parameters = {
        'experiment_path': recycling_experiment_path,
        'stopping_criterion': stopping_criterion
    }

    prc_macros_file = os.path.join(macros_path, 'preprocess_macro.java')
    fuel_macros_file = os.path.join(load_macros_experiment_path, 'fuel_macro.java')
    rec_macros_file = os.path.join(recycling_macros_experiment_path, 'recycle_macro.java')
    run_macros_file = os.path.join(recycling_macros_experiment_path, 'run_macros.java')

    for directory in directories_list:
        create_directory(directory)

    model_file = os.path.join(MODEL_PATH, 'init_model.sim')

    mg.preprocessor_settings(prc_macros_file, model_parameters, model_file)

    load_model_file = os.path.join(load_model_experiment_path, "load_"+str(load)+".sim")

    mg.fuel_settings(fuel_macros_file, fuel_parameters, load_model_file)

    exp_file = os.path.join(recycling_experiment_path, "recycling_"+str(recycling)+".sim")

    mg.fgm_table_settings(rec_macros_file, recycling_parameters, exp_file)
    mg.setting_and_running_solver(run_macros_file, solver_parameters, exp_file)

    run_macros(prc_macros_file, new_model=True)
    run_macros(fuel_macros_file, model_file)
    run_macros(rec_macros_file, load_model_file)
    run_macros(run_macros_file, exp_file, is_gpgpu=True)
    _EXP_FILE = exp_file + "~"
    delete_directory(_EXP_FILE)

    # solver_parameters['stopping_criterion'] = STOPPING_CRITERION
    # mg.setting_and_running_solver(run_macros_file, solver_parameters, EXP_FILE)
    # run_macros(run_macros_file, EXP_FILE, is_gpgpu=True)
    # _EXP_FILE = EXP_FILE + "~"
    # delete_directory(_EXP_FILE)

    # Конец замера времени
    end_time = time.time()

    # Вычисление времени выполнения
    execution_time = end_time - start_time
    print(f"Execution time: {execution_time}")

    # time.sleep(10)
    #
    # processes_name = ["starccm+", "star-ccm+"]
    #
    # for process in processes_name:
    #     terminate_process_by_name(process)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Запуск экспериментов с энергетической установкой ГМУ-45")
    parser.add_argument("angle", type=str, help="Угол наклона лопаток во внешнем контуре")

    args = parser.parse_args()

    run_experiment(args.angle)