import sys
import os
import datetime
import random
import csv
import ifcopenshell 
import ifcopenshell.util.element
import ifcopenshell.util.selector
from ifcopenshell.api import run


def load_model(filepath):
    print("loading " + filepath)
    model = ifcopenshell.open(filepath)
    return model

def get_container(obj):
    if obj is not None:
        container = ifcopenshell.util.element.get_container(obj)
        if container is not None:
            return container.Name

def write_csv(path,filename,datalist):
    print(f"?{filename}")
    f = path + "/" + filename + ".csv"
    print(f"writing {f}")
    with open(f,'w',newline='') as csvfile:
        #writer = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
        writer = csv.writer(csvfile, delimiter=',')
        for item in datalist:
            #print("writing",item)
            writer.writerow(item)

def get_walls(model):
    i=1
    lst = []
    for wall in model.by_type("IfcWall"):
        #print(f"{i}:{wall.Name},container:{get_container(wall)}")
        #d = f"{i},{wall.Name},{get_container(wall)}"
        l = [i,get_container(wall),wall.Name]
        lst.append(l)
        i+=1
    return lst

def wall_type(model):
    walls = model.by_type("IfcWall")
    if len(walls) > 0:
        wall = walls[0]
        if wall is not None:
            print(wall)
            wall_type = ifcopenshell.util.element.get_type(wall)
            if wall_type is not None:
                print(f"The wall type of {wall.Name} is {wall_type.Name}")

def select(model,what):
    print(f"{what}")
    lst = ifcopenshell.util.selector.filter_elements(model, what)
    for elem in lst:
        print(elem.Name)

def create(name,objects):
    print("creating")
    model = ifcopenshell.file()
    project = run("root.create_entity", model, ifc_class="IfcProject", name="My Project")
    run("unit.assign_unit", model)
    context = run("context.add_context", model, context_type="Model")
    body = run("context.add_context", model, context_type="Model",
        context_identifier="Body", target_view="MODEL_VIEW", parent=context)
    site = run("root.create_entity", model, ifc_class="IfcSite", name="My Site")
    building = run("root.create_entity", model, ifc_class="IfcBuilding", name="Building A")
    storey = run("root.create_entity", model, ifc_class="IfcBuildingStorey", name="Ground Floor")
    run("aggregate.assign_object", model, relating_object=project, product=site)
    run("aggregate.assign_object", model, relating_object=site, product=building)
    run("aggregate.assign_object", model, relating_object=building, product=storey)

    if True:
        f = 5
        l = random.random() * 5 * f
        h = random.random() * 3 * f
        t = random.random() * 0.2 * f
        wall = run("root.create_entity", model, ifc_class="IfcWall")
        run("geometry.edit_object_placement", model, product=wall)
        representation = run("geometry.add_wall_representation", model, context=body, length=l, height=h, thickness=t)
        run("geometry.assign_representation", model, product=wall, representation=representation)
        run("spatial.assign_container", model, relating_structure=storey, product=wall)

    if False:
        for item in objects:
            print("adding",item)
            run("spatial.assign_container", model, relating_structure=storey, product=item)

    print("writing " + name)
    model.write(name)

def compute_local(filename,p):
    model = load_model(p)
    lst = get_walls(model)
    select(model,"IfcBuildingStorey")
    print("writing test.ifc")
    create("../output/test.ifc",lst)
    localpath = "../output"
    write_csv(localpath,filename,lst)

def compute_server(filename,p):
    model = load_model(p)
    lst = get_walls(model)
    select(model,"IfcBuildingStorey")
    print("writing test.ifc")
    arg = "test"
    now = str(datetime.datetime.now())
    p = "/home/fordj/SOURCES/FORDJ/fordjx/hackathon-zurich/output/" + arg + "_" + now +  ".ifc"
    create(p,lst)
    localpath = "/home/fordj/SOURCES/FORDJ/fordjx/hackathon-zurich/output"
    write_csv(localpath,filename,lst)

# Server
if len(sys.argv) == 1:
    filename = "duplex"
    p = "/home/fordj/SOURCES/FORDJ/fordjx/hackathon-zurich/ifc/" + filename + ".ifc"
    compute_server(filename,p)
# Local or Server (extract filename)
elif len(sys.argv) > 1:
    use_local = False
    filename = sys.argv[1]
    print(f">> filename:{filename}")
    if use_local:
        p = "../ifc/" + filename + ".ifc"
        compute_local(filename,p)
    else:
        p = "/home/fordj/SOURCES/FORDJ/fordjx/hackathon-zurich/ifc/" + filename + ".ifc"
        compute_server(filename,p)
else:
    print("extract [filepath]")
