import os
from typing import Optional
from helper.fs import FS
from helper.fs import filterModels, listGetFirstValue
from src.model.asm import Assembly
from src.model.enum import Enum
from src.usecases.formatter_usecase import FormatterUseCase
from src.usecases.sdf_generate_world_usecase import SdfGenerateWorldUseCase
from src.model.sdf_geometry import GeometryModel
from distutils.dir_util import copy_tree

SDF_FILE_FORMAT = ".sdf"
CONFIG_PATH = (
    os.path.dirname(os.path.realpath(__file__)) + "/../../mocks/sdf/model.config"
)


class SdfSubAssemblyUseCase(Assembly):
    def call(
        self,
        geometryModels: list[GeometryModel],
        assembly: list[str],
        outPath: str,
        generationFolder: str,
        world: bool,
    ):
        asm = {}
        generateSubAssemblyModels = self.generateSubAssembly(assembly)
        inc = 0
        for key, value in generateSubAssemblyModels.items():
            inc += 1
            if value["assembly"].__len__() != 0:
                model: Optional[GeometryModel] = listGetFirstValue(
                    geometryModels, None, lambda x: x.name == value["assembly"][0]
                )

                if model != None:
                    asm[key] = {
                        "assembly": model.generateSDFatJoinFixed(
                            filterModels(geometryModels, value["assembly"])
                        ),
                        "part": (
                            listGetFirstValue(
                                geometryModels, None, lambda x: x.name == value["part"]
                            )
                        ).includeLink(),
                    }

        self.copy(generationFolder=generationFolder, format="/sdf", outPath=outPath)
        dirPath = outPath + Enum.folderPath
        for el in geometryModels:
            path = dirPath + el.name + "/"
            os.makedirs(path)
            FS.writeFile(
                data=el.toSDF(), filePath=path, fileName="/model" + SDF_FILE_FORMAT
            )
            FS.writeFile(
                data=FS.readFile(CONFIG_PATH),
                filePath=path,
                fileName="/model" + ".config",
            )

        for key, v in asm.items():
            FS.writeFile(
                data=v["assembly"],
                filePath=dirPath,
                fileName="/" + key + SDF_FILE_FORMAT,
            )

        else:
            for key, v in asm.items():
                FS.writeFile(
                    data=SdfGenerateWorldUseCase.call(v["assembly"]),
                    filePath=dirPath,
                    fileName="/" + key + SDF_FILE_FORMAT,
                )

        FormatterUseCase.call(outPath=outPath, format=SDF_FILE_FORMAT)
