import requests

# function for MIDAS Open API
def MidasAPI(method, command, body=None):
    base_url = "base_url_here"
    mapi_key = "your_api_key_here"

    url = base_url + command
    headers = {
        "Content-Type": "application/json",
        "MAPI-Key": mapi_key
    }

    if method == "POST":
        response = requests.post(url=url, headers=headers, json=body)
    elif method == "PUT":
        response = requests.put(url=url, headers=headers, json=body)
    elif method == "GET":
        response = requests.get(url=url, headers=headers)
    elif method == "DELETE":
        response = requests.delete(url=url, headers=headers)

    print(method, command, response.status_code)
    return response.json()

# Unit Setting
unit_dist = "M"     # M, CM, MM, IN, FT
unit_force = "KN"   # KN, N, KGF, TONF, LBF, KIPS

# Input Data
length : float = 10.0
height : float  = 1.0
width : float  = 0.8
add_vertical_load : float = -30.0

# Material Data
mat_standard = "AS17(RC)"
mat_grade = "C32"

# ID (integer)
material_ID : int = 1
section_ID : int = 1
start_node_ID : int = 1
start_elem_ID : int = 1

# Create Unit Body
unit_json = {"Assign" : {
    "1" : {
        "DIST" : unit_dist,
        "FORCE" : unit_force
    }
}}

# Create Material Body
matl_json = {"Assign" : {
    material_ID : {
        "TYPE" : "CONC",
        "NAME" : mat_grade,
        "PARAM" : [
            {
                "P_TYPE":1,
                "STANDARD" : mat_standard,
                "DB" : mat_grade
            }
        ]
    }
}}

# Create Section Body
sect_json = {"Assign" : {
    section_ID : {
        "SECTTYPE" : "DBUSER",
        "SECT_NAME" : "Rectangular",
        "SECT_BEFORE" : {
            "USE_SHEAR_DEFORM" : True,
            "SHAPE": "SB",
            "DATATYPE": 2,
            "SECT_I": {
                "vSIZE" : [height, width]
            }
        }
    }
}}

# Create Node Body
num_divisions = 20
interval = length / int(num_divisions)
x_list = [i * interval for i in range(num_divisions + 1)]

node_json = {"Assign" : {}}

for i, x in enumerate(x_list) :
    node_json["Assign"][start_node_ID + i] = {
        "X" : x,
        "Y" : 0.0,
        "Z" : 0.0
    }

# Create Element Body
elem_json = {"Assign" : {}}

for i in range(num_divisions):
    elem_json["Assign"][start_elem_ID + i] = {
        "TYPE" : "BEAM",
        "MATL" : material_ID,
        "SECT" : section_ID,
        "NODE" : [start_node_ID + i, start_node_ID + i + 1]
    }

# Create Boundary Body
cons_json = {"Assign" : {
    start_node_ID : {
        "ITEMS" : [
            {
                "ID":1,
                "CONSTRAINT" : "1111000"
            }
        ]
    },
    start_node_ID + num_divisions : {
        "ITEMS" : [
            {
                "ID":1,
                "CONSTRAINT" : "0111000"
            }
        ]
    }
}}

# Create LoadCase Body
load_case_name = ["DL", "SIDL"]
load_case_desc = ["Dead Load", "Super Imposed Dead Load"]

stld_json = {"Assign" : {}}

for i in range(len(load_case_name)) :
    stld_json["Assign"][i + 1] = {
        "NAME" : load_case_name[i],
        "TYPE" : "USER",
        "DESC" : load_case_desc[i],
    }

# Create Self-Weight Load Body
bodf_json = {"Assign" : {
    "1" : {
        "LCNAME" : load_case_name[0],
        "FV" :[
            0,
            0,
            -1
        ]
    }
}}

# Create Beam Load Body
bmld_json = {"Assign" : {}}

for i in range(num_divisions) :
    bmld_json["Assign"][start_elem_ID + i] = {
        "ITEMS" :[
            {
                "ID" : 1,
                "LCNAME" : load_case_name[1],
                "CMD" : "BEAM",
                "TYPE" : "UNILOAD",
                "DIRECTION" : "GZ",
                "D" : [
                    0,
                    1
                ],
                "P" : [
                    add_vertical_load,
                    add_vertical_load
                ]
            }
        ]
    }

# Create Load Combination Body
load_factor = [1.2, 1.5]
lcom_gen_json = {"Assign" : {
    "1" : {
        "NAME" : "Comb1",
        "ACTIVE" : "ACTIVE",
        "iTYPE" : 0,
        "vCOMB" :[
            {
                "ANAL" : "ST",
                "LCNAME" : load_case_name[0],
                "FACTOR" : load_factor[0]
            },
            {
                "ANAL" : "ST",
                "LCNAME" : load_case_name[1],
                "FACTOR" : load_factor[1]
            }
        ]
    }
}}

# SEND DATA TO MIDAS CIVIL
# Create New file
file_res = MidasAPI("POST", "/doc/new", {})
# Sending Request
unit_res = MidasAPI("PUT", "/db/unit", unit_json)
matl_res = MidasAPI("POST", "/db/matl", matl_json)
sect_res = MidasAPI("POST", "/db/sect", sect_json)
node_res = MidasAPI("POST", "/db/node", node_json)
elem_res = MidasAPI("POST", "/db/elem", elem_json)
cons_res = MidasAPI( "POST", "/db/cons", cons_json)
stld_res = MidasAPI("POST", "/db/stld", stld_json)
bodf_json = MidasAPI("POST", "/db/bodf", bodf_json)
bmld_res = MidasAPI("POST", "/db/bmld", bmld_json)
lcom_gen_res = MidasAPI("POST", "/db/lcom-gen", lcom_gen_json)