#!/usr/bin/freecadcmd

import os
import FreeCAD # type: ignore
import Mesh # type: ignore

# Define the project root directory
project_root = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))

# Define the directories for CAD files and 3MF export files
printed_cad_dir = os.path.join(project_root, "cad", "printed")
printed_3mf_dir = os.path.join(project_root, "3mf")

# Create the 3mf directory if it doesn't exist
os.makedirs(printed_3mf_dir, exist_ok=True)

# List to keep track of files that failed to export
failed_files = []

# Traverse the printed CAD directory and its subdirectories
for root, dirs, files in os.walk(printed_cad_dir):
    for file in files:
        if file.endswith(".FCStd"):
            # Absolute path of the CAD file
            file_path = os.path.join(root, file)

            FreeCAD.Console.PrintMessage(f"\nProcessing {file_path}\n")

            # Open the FreeCAD document
            doc = FreeCAD.openDocument(file_path)
            FreeCAD.setActiveDocument(doc.Name)
            FreeCAD.ActiveDocument.recompute()

            # Iterate over all objects in the document
            for obj in doc.Objects:
                # Check if the object is Std_Part
                if obj.TypeId == 'App::Part':
                    # Construct the output path for the 3MF file using the label
                    output_path = os.path.join(
                        printed_3mf_dir, os.path.relpath(root, printed_cad_dir), f"{obj.Label}.3mf"
                    )
                    # Create the output directory if it doesn't already exist
                    os.makedirs(os.path.dirname(output_path), exist_ok=True)

                    try:
                        # Export the part to a 3MF file
                        Mesh.export([obj], output_path)
                        FreeCAD.Console.PrintMessage(f"Exported {obj.Label} to {output_path}\n")
                    except Exception as e:
                        FreeCAD.Console.PrintError(f"Error exporting {obj.Label}: {e}\n")
                        failed_files.append(file_path)

            # Close the FreeCAD document
            FreeCAD.closeDocument(doc.Name)

# Print the result of the export process
if failed_files:
    FreeCAD.Console.PrintError("\nThe following files failed to export:\n")
    for file in failed_files:
        FreeCAD.Console.PrintError(f" - {file}\n")
else:
    FreeCAD.Console.PrintMessage("\nAll files have been exported successfully.\n")