# This file is part of the faebryk project
# SPDX-License-Identifier: MIT

import json
import logging
from pathlib import Path

import faebryk.core.node as fabll
import faebryk.library._F as F
from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer
from faebryk.libs.util import not_none

logger = logging.getLogger(__name__)


def _get_testpoints(app: fabll.Node) -> list[F.TestPoint]:
    return [
        testpoint
        for testpoint in app.get_children(
            types=F.TestPoint,
            direct_only=False,
            include_root=True,
        )
        if testpoint.has_trait(F.Footprints.has_associated_footprint)
        and testpoint.get_trait(F.Footprints.has_associated_footprint)
        .get_footprint()
        .has_trait(F.KiCadFootprints.has_associated_kicad_pcb_footprint)
    ]


def export_testpoints(
    app: fabll.Node,
    testpoints_file: Path,
):
    """
    Get all testpoints from the application and export their information to a JSON file
    """
    testpoint_data: dict[str, dict] = {}
    testpoints = _get_testpoints(app)

    for testpoint in testpoints:
        designator = not_none(testpoint.get_trait(F.has_designator).get_designator())
        full_name = testpoint.get_full_name()
        fp = testpoint.get_trait(F.Footprints.has_associated_footprint).get_footprint()
        footprint = PCB_Transformer.get_kicad_pcb_fp(fp)  # get KiCad footprint
        position = footprint.at
        layer = footprint.layer
        library_name = footprint.name

        # Get single connected net name
        net_name = (
            testpoint.contact.get().get_trait(F.has_net_name).get_name() or "no-net"
        )

        testpoint_data[designator] = {
            "testpoint_name": full_name,
            "net_name": net_name,
            "footprint_name": library_name,
            "position": {"x": position.x, "y": position.y, "rotation": position.r},
            "layer": layer,
        }

    with open(testpoints_file, "w", encoding="utf-8") as f:
        json.dump(obj=testpoint_data, fp=f, indent=4)
