"""
JSON v0/v1 compatibility layer for MIR Call instructions.

This module provides utilities to normalize JSON v0 and v1 formats
for MIR Call instructions, making it easier to remove v0 in Phase 124+.

JSON v0 format:
    {"method": "log", "box_type": "ConsoleBox", "receiver": 42}

JSON v1 format:
    {"name": "log", "box_name": "ConsoleBox", "receiver": 42}
"""

from typing import Dict, Any, Optional


class MirCallCompat:
    """JSON v0/v1 compatibility processor for MIR Call instructions."""

    @staticmethod
    def normalize_callee(callee_json: Dict[str, Any]) -> Dict[str, Any]:
        """
        Normalize JSON v0/v1 callee format to unified internal format.

        Args:
            callee_json: Callee dict from MIR Call instruction

        Returns:
            Normalized dict with consistent keys:
            {
                "type": "Global" | "Method" | "Constructor" | "Closure" | "Value" | "Extern",
                "name": str (function/method name),
                "box_name": str (for Method/Constructor),
                "receiver": int (for Method),
                ... other fields
            }

        Examples:
            v0: {"method": "log", "box_type": "ConsoleBox"}
            v1: {"name": "log", "box_name": "ConsoleBox"}
            → {"type": "Method", "name": "log", "box_name": "ConsoleBox"}
        """
        if not callee_json:
            return {}

        # Extract type (should already be present in both v0/v1)
        callee_type = callee_json.get("type")

        # Normalize method/function name (v0: "method", v1: "name")
        name = callee_json.get("name") or callee_json.get("method")

        # Normalize box type name (v0: "box_type", v1: "box_name")
        box_name = callee_json.get("box_name") or callee_json.get("box_type")

        # Build normalized result
        normalized = {
            "type": callee_type,
        }

        if name is not None:
            normalized["name"] = name

        if box_name is not None:
            normalized["box_name"] = box_name

        # Copy other fields as-is
        for key in ["receiver", "value", "params", "captures", "me_capture", "certainty"]:
            if key in callee_json:
                normalized[key] = callee_json[key]

        return normalized

    @staticmethod
    def detect_format_version(callee_json: Dict[str, Any]) -> int:
        """
        Detect whether callee JSON is v0 or v1 format.

        Args:
            callee_json: Callee dict from MIR Call instruction

        Returns:
            0 for v0 format (uses "method"/"box_type")
            1 for v1 format (uses "name"/"box_name")

        Raises:
            ValueError: If format cannot be determined
        """
        if not callee_json:
            raise ValueError("Empty callee JSON")

        # Check for v0 markers
        if "method" in callee_json or "box_type" in callee_json:
            return 0

        # Check for v1 markers
        if "name" in callee_json or "box_name" in callee_json:
            return 1

        # No clear markers - check callee type
        if callee_json.get("type") in ["Global", "Method", "Constructor", "Extern"]:
            # Modern format (v1)
            return 1

        raise ValueError(f"Unknown callee format: {callee_json}")

    @staticmethod
    def is_v0_format(callee_json: Dict[str, Any]) -> bool:
        """Check if callee JSON uses v0 format."""
        try:
            return MirCallCompat.detect_format_version(callee_json) == 0
        except ValueError:
            return False

    @staticmethod
    def is_v1_format(callee_json: Dict[str, Any]) -> bool:
        """Check if callee JSON uses v1 format."""
        try:
            return MirCallCompat.detect_format_version(callee_json) == 1
        except ValueError:
            return False
