import json

import FreeCAD as App

from freecad_mutation_evidence import capture_property_mutation


COMMIT = "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d"


def primitive_case(type_id, properties, property_name, edited_value):
    document = App.newDocument("{}MutationOracle".format(type_id.replace("::", "")))
    try:
        feature = document.addObject(type_id, "Feature")
        for name, value in properties.items():
            setattr(feature, name, value)
        mutation = capture_property_mutation(document, feature, property_name, edited_value)
        return mutation
    finally:
        App.closeDocument(document.Name)


def boolean_case(type_id):
    document = App.newDocument("{}MutationOracle".format(type_id.replace("::", "")))
    try:
        base = document.addObject("Part::Box", "Base")
        base.Length, base.Width, base.Height = 10.0, 9.0, 8.0
        tool = document.addObject("Part::Cylinder", "Tool")
        tool.Radius, tool.Height = 2.0, 12.0
        tool.Placement.Base = App.Vector(5.0, 4.5, -2.0)
        feature = document.addObject(type_id, "Feature")
        feature.Base, feature.Tool = base, tool
        return capture_property_mutation(document, feature, "Radius", 2.5, target=tool, property_path="Tool.Radius")
    finally:
        App.closeDocument(document.Name)


cases = [
    primitive_case("Part::Box", {"Length": 10.0, "Width": 8.0, "Height": 6.0}, "Length", 12.0),
    primitive_case("Part::Cylinder", {"Radius": 3.0, "Height": 8.0, "Angle": 360.0}, "Radius", 3.5),
    primitive_case("Part::Sphere", {"Radius": 4.0}, "Radius", 4.5),
    primitive_case("Part::Ellipsoid", {"Radius1": 2.0, "Radius2": 4.0, "Radius3": 0.0, "Angle1": -90.0, "Angle2": 90.0, "Angle3": 360.0}, "Radius1", 2.5),
    primitive_case("Part::Cone", {"Radius1": 4.0, "Radius2": 2.0, "Height": 8.0, "Angle": 360.0}, "Height", 10.0),
    primitive_case("Part::Torus", {"Radius1": 10.0, "Radius2": 2.0, "Angle1": -180.0, "Angle2": 180.0, "Angle3": 270.0}, "Radius2", 2.5),
    primitive_case("Part::Helix", {"Pitch": 3.0, "Height": 6.0, "Radius": 2.0, "Angle": 0.0, "SegmentLength": 0.0}, "Radius", 2.5),
    primitive_case("Part::Prism", {"Polygon": 6, "Circumradius": 2.0, "Height": 10.0, "FirstAngle": 10.0, "SecondAngle": -5.0}, "Height", 12.0),
    primitive_case("Part::Wedge", {"Xmin": 0.0, "Ymin": 0.0, "Zmin": 0.0, "Z2min": 0.0, "X2min": 0.0, "Xmax": 10.0, "Ymax": 10.0, "Zmax": 10.0, "Z2max": 8.0, "X2max": 8.0}, "X2max", 7.0),
    boolean_case("Part::Fuse"),
    boolean_case("Part::Cut"),
    boolean_case("Part::Common"),
]

report = {
    "schemaVersion": 1,
    "baselineId": "freecad-1.1.1-core-parameter-mutation-oracle",
    "freecadVersion": ".".join(str(value) for value in App.Version()[:3]),
    "gitCommit": COMMIT,
    "status": "pass" if all(case["status"] == "pass" for case in cases) else "failed",
    "summary": {
        "families": len(cases),
        "passed": sum(1 for case in cases if case["status"] == "pass"),
        "shapeChanged": sum(1 for case in cases if case["shapeChanged"]),
        "restoredExactly": sum(1 for case in cases if case["restoredExactly"]),
    },
    "cases": cases,
}
print("FREECAD_CORE_PARAMETER_MUTATION_RESULT=" + json.dumps(report, sort_keys=True, separators=(",", ":")))
