"""
PACT-aware context snapshot exporter.

Extracts PACT structure metadata for efficient visualization.
"""

from typing import Dict, List, Any


class ContextExporter:
    """PACT-aware context snapshot exporter."""

    @staticmethod
    def analyze_pact_structure(context) -> Dict:
        """
        Extract PACT-specific metadata for efficient visualization.

        Returns:
            Dict with keys: depths, components, odi_state, ttl_components, registry
        """
        return {
            "depths": ContextExporter._get_depth_info(context),
            "components": ContextExporter._get_component_info(context),
            "odi_state": ContextExporter._get_odi_state(context),
            "ttl_components": ContextExporter._get_ttl_components(context),
            "registry": ContextExporter._get_registry_state(context),
        }

    @staticmethod
    def _get_depth_info(context) -> Dict:
        """
        Analyze depth array structure.

        Returns:
            Dict mapping depth -> {role, component_count}
        """
        depths = {}

        # Safely iterate over content
        content = getattr(context, "content", [])
        if not content:
            return depths

        for depth_comp in content:
            depth = getattr(depth_comp, "depth", None)
            if depth is not None:
                # Try to get component count by traversing branch
                try:
                    if hasattr(context, "traverse_branch"):
                        component_count = len(list(context.traverse_branch(depth)))
                    else:
                        component_count = 0
                except:
                    component_count = 0

                depths[depth] = {
                    "role": getattr(depth_comp, "role", None),
                    "component_count": component_count,
                }

        return depths

    @staticmethod
    def _get_component_info(context) -> Dict:
        """
        Component type distribution.

        Returns:
            Dict mapping component type name -> count
        """
        types = {}

        # Safely traverse context
        if hasattr(context, "traverse"):
            try:
                for comp in context.traverse():
                    comp_type = type(comp).__name__
                    types[comp_type] = types.get(comp_type, 0) + 1
            except:
                pass

        return types

    @staticmethod
    def _get_odi_state(context) -> List[Dict]:
        """
        Track ODI-relevant components (permanent/sticky).

        Returns:
            List of dicts with: id, type, is_permanent, is_sticky
        """
        odi_components = []

        # Safely traverse context
        if hasattr(context, "traverse"):
            try:
                for comp in context.traverse():
                    ttl = getattr(comp, "ttl", None)
                    cad = getattr(comp, "cadence", None)

                    # Permanent or sticky = participates in ODI
                    if ttl is None or (ttl == 1 and cad == 1):
                        odi_components.append(
                            {
                                "id": comp.id,
                                "type": type(comp).__name__,
                                "is_permanent": ttl is None,
                                "is_sticky": ttl == 1 and cad == 1,
                            }
                        )
            except:
                pass

        return odi_components

    @staticmethod
    def _get_ttl_components(context) -> List[Dict]:
        """
        Track TTL lifecycle components.

        Returns:
            List of dicts with: id, type, ttl, cadence, age, expires_in
        """
        ttl_comps = []

        # Safely traverse context
        if hasattr(context, "traverse"):
            try:
                for comp in context.traverse():
                    ttl = getattr(comp, "ttl", None)
                    if ttl is not None:
                        age = getattr(comp, "age", 0)
                        ttl_comps.append(
                            {
                                "id": comp.id,
                                "type": type(comp).__name__,
                                "ttl": ttl,
                                "cadence": getattr(comp, "cadence", None),
                                "age": age,
                                "expires_in": ttl - age,
                            }
                        )
            except:
                pass

        return ttl_comps

    @staticmethod
    def _get_registry_state(context) -> Dict:
        """
        Export tool registry state.

        Returns:
            Dict with: tool_pairs, tool_executions
        """
        registry = getattr(context, "_registry", None)
        if not registry:
            return {"tool_pairs": 0, "tool_executions": {}}

        tool_pairs = getattr(registry, "_tool_pairs", {})
        tool_executions = getattr(registry, "_tool_executions", {})

        return {
            "tool_pairs": len(tool_pairs),
            "tool_executions": {
                tool: len(calls) for tool, calls in tool_executions.items()
            },
        }
