import os
from extensions.list import CoreList
from extensions.dict import CoreDict
from helpers.freecadtest import FreeCadASPGenerationTestController
from models.adjacency_matrix_model import (
    AdjacencyMatrixModel,
)
from usecases.check_object_has_touches_use_case import (
    CheckObjectHasTouchesUseCase,
)
from usecases.clusterisation_sequences_use_case import (
    ClusterisationSequenceUseCase,
)
from usecases.check_sequence_use_case import (
    CheckSequenceUsecase,
)
from usecases.env_reader_use_case import (
    EnvReaderUseCase,
)
from usecases.exit_freecad_use_case import (
    ExitFreeCadUseCase,
)
from usecases.intersection_geometry_use_case import (
    IntersectionGeometryUseCase,
)
from usecases.open_freecad_document_use_case import (
    OpenFreeCadDocumentUseCase,
)


from mocks.mock_structure import bottle_jack_mock_structure, simple_cube_mock_structure


def main():
    try:
        EnvReaderUseCase.call().either(
            leftF=lambda environment: (
                OpenFreeCadDocumentUseCase.call(environment.cadFilePath).either(
                    leftF=lambda _: (
                        (
                            CheckObjectHasTouchesUseCase()
                            .call(environment.solidBodyPadding)
                            .either(
                                leftF=lambda adjaxedMatrix: (
                                    adjaxedMatrix.sequencesToFileSystem(
                                        environment.outPath,
                                        environment.sequencesFixed,
                                    ),
                                    IntersectionGeometryUseCase.call(
                                        adjaxedMatrix.matrixGetUniqueContact(),
                                        environment.outPath,
                                    ),
                                    adjaxedMatrix.matrixToFileSystem(
                                        environment.outPath,
                                    ),
                                    ClusterisationSequenceUseCase(environment.outPath),
                                    ExitFreeCadUseCase.call(),
                                ),
                                rightF=lambda error: error.toFileSystem(
                                    environment.outPath
                                ),
                            ),
                        )
                    ),
                    rightF=lambda error: print(error),
                ),
            ),
            rightF=lambda error: print(error),
        )

    except Exception as error:
        print(error)
        ExitFreeCadUseCase.call()


# main()


def test():
    try:
        mocksFolder = os.path.dirname(__file__) + "/mocks/"

        outFolder = os.path.dirname(__file__) + "/out/"

        FreeCadASPGenerationTestController("test adjaxed matrix simple cube").test(
            assertFn=lambda model: CoreList(model.all_parts).equal(
                simple_cube_mock_structure
            ),
            execComposition=lambda _: (
                CheckObjectHasTouchesUseCase()
                .call(0)
                .either(
                    leftF=lambda matrix: matrix.matrixToFileSystem(outFolder),
                    rightF=lambda error: print(error),
                )
            ),
            documentPath=mocksFolder + "simple_assembly_with_two_cubes.FCStd",
            modelName=AdjacencyMatrixModel.fileName,
            model=AdjacencyMatrixModel,
        )

        FreeCadASPGenerationTestController(
            "test adjaxed matrix vs structure of document"
        ).test(
            assertFn=lambda model: CoreDict(model.matrix).isEquivalentByKeys(
                bottle_jack_mock_structure
            ),
            execComposition=lambda _: (
                CheckObjectHasTouchesUseCase()
                .call(0)
                .either(
                    leftF=lambda matrix: matrix.matrixToFileSystem(outFolder),
                    rightF=lambda error: print(error),
                )
            ),
            documentPath=mocksFolder + "bottle_jack.FCStd",
            modelName=AdjacencyMatrixModel.fileName,
            model=AdjacencyMatrixModel,
        )

        FreeCadASPGenerationTestController(
            "test adjacency matrix keys vs allparts"
        ).test(
            assertFn=lambda model: CoreDict(model.matrix).isMatchByKeys(
                model.all_parts
            ),
            execComposition=lambda _: (
                CheckObjectHasTouchesUseCase()
                .call(0)
                .either(
                    leftF=lambda matrix: (matrix.matrixToFileSystem(outFolder)),
                    rightF=lambda error: print(error),
                )
            ),
            documentPath=mocksFolder + "bottle_jack.FCStd",
            modelName=AdjacencyMatrixModel.fileName,
            model=AdjacencyMatrixModel,
        )

        FreeCadASPGenerationTestController("test all parts vs  assembly sequence").test(
            assertFn=lambda model: CheckSequenceUsecase(
                ClusterisationSequenceUseCase(outFolder)
            ).isCorrectByParts(model.all_parts),
            execComposition=lambda _: (
                CheckObjectHasTouchesUseCase()
                .call(0)
                .either(
                    leftF=lambda matrix: (
                        matrix.matrixToFileSystem(outFolder),
                        ClusterisationSequenceUseCase(outFolder),
                    ),
                    rightF=lambda error: print(error),
                )
            ),
            documentPath=mocksFolder + "bottle_jack.FCStd",
            modelName=AdjacencyMatrixModel.fileName,
            model=AdjacencyMatrixModel,
        )

        ExitFreeCadUseCase.call()
    except Exception as e:
        print(e)
        print("test error")
        ExitFreeCadUseCase.call()
    pass


test()
