import os
import ideastatica_connection_api.connection_api_service_attacher as connection_api_service_attacher
import ideastatica_connection_api
from pathlib import Path
import numpy as np
import math
import subprocess
import time

# Path to IdeaStatiCa.ConnectionRestApi.exe typically in C:\Program Files\IDEA StatiCa\StatiCa 25.0
get_api_path = r"C:/Program Files/IDEA StatiCa/StatiCa 25.0/IdeaStatiCa.ConnectionRestApi.exe"

api_run = subprocess.Popen(get_api_path, creationflags=subprocess.CREATE_NEW_CONSOLE)
time.sleep(5)

baseUrl = "http://localhost:5000"

# Path into folder with your python script and connection module
script_dir = Path(__file__).resolve().parent
project_file_path = script_dir / "T-stub.ideaCon"

# Create client attached to already running service
with connection_api_service_attacher.ConnectionApiServiceAttacher(baseUrl).create_api_client() as api_client:
    try:
        # Open project
        print("Opening project %s" % project_file_path)
            
        openedProject = api_client.project.open_project_from_filepath(project_file_path)
        activeProjectId = api_client.project.active_project_id

        # Get list of all connections in the project
        connections_in_project = api_client.connection.get_connections(api_client.project.active_project_id)

        # Iterate project items
        for connection in connections_in_project:
            print("Processing connection : %s" % connection)
            
            # Run stress-strain CBFEM analysis for the first connection
            calc_params = ideastatica_connection_api.ConCalculationParameter()
            calc_params.connection_ids = [connection.id]
            conn_ID = calc_params.connection_ids[0]
            
            for parameter in np.arange(0.008, 0.042, 0.002):
                
                t=parameter
 
                idea_parameter_update = [
                    {
                        "key": "t",
                        "expression": str(parameter)
                    }
                ]
                # Get parameters
                api_response = api_client.parameter.get_parameters(activeProjectId,conn_ID)

                b = api_response[1].expression
                e = api_response[2].expression
                # Update parameters for the connection connectionId in the project projectId by values passed in parameters
                api_response = api_client.parameter.update_parameters(activeProjectId, conn_ID, idea_parameter_update=idea_parameter_update)

                # Calculate project item
                con1_cbfem_results = api_client.calculation.calculate(api_client.project.active_project_id, calc_params)
                                               
                results = api_client.calculation.get_results(api_client.project.active_project_id, calc_params)

                analysis = results[0].check_res_summary[0].check_value
                plate_strain = results[0].check_res_summary[1].check_value
                bolt = results[0].check_res_summary[2].check_value
                weld = results[0].check_res_summary[3].check_value

                Load = api_client.load_effect.get_load_effects(activeProjectId,connection.id)
                AppliedLoad=Load[0].member_loadings[0].section_load.n

                FT_Rd_CBFEM = AppliedLoad*analysis/100000

                if plate_strain>3:
                    mode_CBFEM = 1 
                elif plate_strain > 0.3:
                    mode_CBFEM = 2
                else:
                    mode_CBFEM = 3

                #Component method calculation
                # Geometry input
                tw = 20            # Web plate thickness [mm]
                t = t*1000             # Flange plate thickness [mm]
                b = float(b)*1000            # Plate width [mm]
                h = 220            # Plate height [mm]
                a = 10             # Fillet weld throat thickness [mm]
                e = float(e)*1000             # Bolt to edge distance [mm]

                # Derived geometric parameters
                m = h / 2 - e - tw / 2 - math.sqrt(2) * a *0.8
                n = min(1.25 * m, e)

                # Bolt parameters
                dw = 38            # Bolt head or nut diameter [mm]
                ew = dw / 4        # Edge distance at washer contact [mm]
                As = 353           # Bolt tensile stress area [mm?]

                # Material properties
                fy = 355           # Plate yield strength [MPa]
                fub = 800          # Bolt ultimate strength [MPa]
                gamma_M0 = 1.0
                gamma_M2 = 1.25

                # Bolt tensile resistance (EN 1993-1-8 Table 3.4)
                k2 = 0.9
                Ft_Rd = k2 * fub * As / gamma_M2   # [N]

                # Yield line lengths
                leff_cp = min(2 * math.pi * m, math.pi * m + 2 * e)
                leff_nc = min(4 * m + 1.25 * e, b)
                leff_1 = min(leff_cp, leff_nc)
                leff_2 = leff_nc

                # Plastic bending resistances (EN 1993-1-8 Table 6.2)
                Mpl1_Rd = 0.25 * leff_1 * t**2 * fy / gamma_M0   # [Nmm]
                Mpl2_Rd = 0.25 * leff_2 * t**2 * fy / gamma_M0   # [Nmm]

                # T-stub resistances
                FT_1_Rd = ((8 * n - 2 * ew) * Mpl1_Rd) / (2 * m * n - ew * (m + n))   # [N]
                FT_2_Rd = (2 * Mpl2_Rd + n * 2 * Ft_Rd) / (m + n)               # [N]
                FT_3_Rd = 2 * Ft_Rd                                  # [N]

                FT_Rd = min(FT_1_Rd, FT_2_Rd, FT_3_Rd)   #[N]

                # Failure mode determination
                if FT_Rd == FT_1_Rd:
                    mode_CM = 1
                elif FT_Rd == FT_2_Rd:
                    mode_CM = 2
                else:
                    mode_CM = 3

                # Print all results into one row               
                print(connection.name, plate_strain, weld, bolt, t, b, e, analysis/100, FT_Rd_CBFEM, mode_CBFEM, FT_Rd/1000, mode_CM, FT_Rd_CBFEM/(FT_Rd/1000), sep=';')

    except Exception as e:
       print("Operation failed : %s\n" % e)     





