"""
OpenAI/Codex Adapter for Mantic Tools

Converts Mantic tools to OpenAI function calling format.
Compatible with GPT-4, GPT-4o, and Codex.

Includes both Friction tools (7) and Emergence tools (7) = 14 total.
"""

import sys
import os

# Avoid mutating sys.path on import; only adjust for direct script execution.
if __name__ == "__main__":
    _repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    if _repo_root not in sys.path:
        sys.path.insert(0, _repo_root)

# Friction tools (divergence detection)
from tools import (
    healthcare_phenotype_genotype,
    finance_regime_conflict,
    cyber_attribution_resolver,
    climate_maladaptation,
    legal_precedent_drift,
    military_friction_forecast,
    social_narrative_rupture,
)

# Emergence tools (confluence detection)
from tools import (
    healthcare_precision_therapeutic,
    finance_confluence_alpha,
    cyber_adversary_overreach,
    climate_resilience_multiplier,
    legal_precedent_seeding,
    military_strategic_initiative,
    social_catalytic_alignment,
)

# Optional override inputs (bounded internally by tools)
OVERRIDE_PROPERTIES = {
    "threshold_override": {
        "type": "object",
        "description": "Optional per-threshold overrides (bounded internally). Keys vary by tool.",
        "additionalProperties": {"type": "number"}
    },
    "temporal_config": {
        "type": "object",
        "description": "Optional temporal kernel config (bounded internally). Requires kernel_type and t.",
        "properties": {
            "kernel_type": {"type": "string", "description": "Temporal kernel type (domain-allowed)"},
            "alpha": {"type": "number", "description": "Sensitivity (bounded)"},
            "n": {"type": "number", "description": "Novelty (bounded)"},
            "t": {"type": "number", "description": "Time delta"},
            "t0": {"type": "number", "description": "S-curve inflection point"},
            "exponent": {"type": "number", "description": "Power-law exponent"},
            "frequency": {"type": "number", "description": "Oscillation frequency"},
            "memory_strength": {"type": "number", "description": "Memory strength"}
        }
    }
}


# Map tool IDs to detection functions (14 tools total)
TOOL_MAP = {
    # Friction tools (7)
    "healthcare_phenotype_genotype": healthcare_phenotype_genotype.detect,
    "finance_regime_conflict": finance_regime_conflict.detect,
    "cyber_attribution_resolver": cyber_attribution_resolver.detect,
    "climate_maladaptation": climate_maladaptation.detect,
    "legal_precedent_drift": legal_precedent_drift.detect,
    "military_friction_forecast": military_friction_forecast.detect,
    "social_narrative_rupture": social_narrative_rupture.detect,
    # Emergence tools (7)
    "healthcare_precision_therapeutic": healthcare_precision_therapeutic.detect,
    "finance_confluence_alpha": finance_confluence_alpha.detect,
    "cyber_adversary_overreach": cyber_adversary_overreach.detect,
    "climate_resilience_multiplier": climate_resilience_multiplier.detect,
    "legal_precedent_seeding": legal_precedent_seeding.detect,
    "military_strategic_initiative": military_strategic_initiative.detect,
    "social_catalytic_alignment": social_catalytic_alignment.detect,
}


def get_openai_tools():
    """
    Return OpenAI function calling schema for all Mantic tools.

    Returns:
        list: OpenAI function definitions (14 tools)
    """
    friction_tools = [
        {
            "type": "function",
            "function": {
                "name": "healthcare_phenotype_genotype",
                "description": "FRICTION: Detects when genomic risk doesn't match phenotypic presentation, indicating environmental buffering or psychosocial resilience.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "phenotypic": {"type": "number", "description": "Current symptoms/vitals (0-1)"},
                        "genomic": {"type": "number", "description": "Genetic risk score (0-1)"},
                        "environmental": {"type": "number", "description": "Exposure load (0-1)"},
                        "psychosocial": {"type": "number", "description": "Stress/resilience (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["phenotypic", "genomic", "environmental", "psychosocial"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "finance_regime_conflict",
                "description": "FRICTION: Spots when technical price action contradicts fundamentals, flow, or risk signals.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "technical": {"type": "number", "description": "Price action signals (0-1)"},
                        "macro": {"type": "number", "description": "Fundamental indicators (0-1)"},
                        "flow": {"type": "number", "description": "Capital flow direction (-1 to 1)"},
                        "risk": {"type": "number", "description": "Risk appetite metrics (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["technical", "macro", "flow", "risk"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "cyber_attribution_resolver",
                "description": "FRICTION: Scores confidence when technical sophistication doesn't align with geopolitical context.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "technical": {"type": "number", "description": "Technical sophistication (0-1)"},
                        "threat_intel": {"type": "number", "description": "Threat intel confidence (0-1)"},
                        "operational_impact": {"type": "number", "description": "Operational impact severity (0-1)"},
                        "geopolitical": {"type": "number", "description": "Geopolitical context alignment (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["technical", "threat_intel", "operational_impact", "geopolitical"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "climate_maladaptation",
                "description": "FRICTION: Blocks solutions that solve immediate micro problems but create macro/meta harms.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "atmospheric": {"type": "number", "description": "Atmospheric metrics (0-1)"},
                        "ecological": {"type": "number", "description": "Ecosystem health (0-1)"},
                        "infrastructure": {"type": "number", "description": "Infrastructure resilience (0-1)"},
                        "policy": {"type": "number", "description": "Policy coherence (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["atmospheric", "ecological", "infrastructure", "policy"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "legal_precedent_drift",
                "description": "FRICTION: Warns when judicial philosophy shifts threaten current precedent-based strategies.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "black_letter": {"type": "number", "description": "Statutory text alignment (0-1)"},
                        "precedent": {"type": "number", "description": "Precedent consistency (0-1)"},
                        "operational": {"type": "number", "description": "Implementation feasibility (0-1)"},
                        "socio_political": {"type": "number", "description": "Social/political context (-1 to 1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["black_letter", "precedent", "operational", "socio_political"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "military_friction_forecast",
                "description": "FRICTION: Identifies where tactical plans hit logistics or political constraints.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "maneuver": {"type": "number", "description": "Tactical maneuver feasibility (0-1)"},
                        "intelligence": {"type": "number", "description": "Intelligence confidence (0-1)"},
                        "sustainment": {"type": "number", "description": "Logistics sustainability (0-1)"},
                        "political": {"type": "number", "description": "Political authorization (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["maneuver", "intelligence", "sustainment", "political"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "social_narrative_rupture",
                "description": "FRICTION: Catches virality that outpaces institutional sense-making capacity.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "individual": {"type": "number", "description": "Sentiment velocity (0-1)"},
                        "network": {"type": "number", "description": "Propagation speed (0-1)"},
                        "institutional": {"type": "number", "description": "Response lag (0-1)"},
                        "cultural": {"type": "number", "description": "Archetype alignment (-1 to 1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["individual", "network", "institutional", "cultural"]
                }
            }
        }
    ]

    emergence_tools = [
        {
            "type": "function",
            "function": {
                "name": "healthcare_precision_therapeutic",
                "description": "CONFLUENCE: Identifies rare alignment of genomic predisposition, environmental readiness, phenotypic timing, and psychosocial engagement for maximum treatment efficacy.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "genomic_predisposition": {"type": "number", "description": "Genetic readiness for treatment (0-1)"},
                        "environmental_readiness": {"type": "number", "description": "Exposure/toxin levels favorable (0-1)"},
                        "phenotypic_timing": {"type": "number", "description": "Disease progression stage optimal (0-1)"},
                        "psychosocial_engagement": {"type": "number", "description": "Patient motivation/support high (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["genomic_predisposition", "environmental_readiness", "phenotypic_timing", "psychosocial_engagement"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "finance_confluence_alpha",
                "description": "CONFLUENCE: Detects asymmetric opportunity when technical setup, macro tailwind, flow positioning, and risk compression achieve directional harmony.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "technical_setup": {"type": "number", "description": "Technical indicators favorable (0-1)"},
                        "macro_tailwind": {"type": "number", "description": "Fundamental/macro support (0-1)"},
                        "flow_positioning": {"type": "number", "description": "Crowd positioning (-1 to 1, extreme = contrarian signal)"},
                        "risk_compression": {"type": "number", "description": "Risk appetite favorable (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["technical_setup", "macro_tailwind", "flow_positioning", "risk_compression"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "cyber_adversary_overreach",
                "description": "CONFLUENCE: Identifies defensive advantage windows when attacker TTPs are stretched, geopolitically pressured, and operationally fatigued.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "threat_intel_stretch": {"type": "number", "description": "Attacker TTPs overextended/visible (0-1)"},
                        "geopolitical_pressure": {"type": "number", "description": "External pressure on attacker (0-1)"},
                        "operational_hardening": {"type": "number", "description": "Defender readiness/hardening (0-1)"},
                        "tool_reuse_fatigue": {"type": "number", "description": "Attacker tool reuse/indicators (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["threat_intel_stretch", "geopolitical_pressure", "operational_hardening", "tool_reuse_fatigue"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "climate_resilience_multiplier",
                "description": "CONFLUENCE: Surfaces interventions with positive cross-domain coupling solving multiple layer problems simultaneously.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "atmospheric_benefit": {"type": "number", "description": "Atmospheric/climate benefit (0-1)"},
                        "ecological_benefit": {"type": "number", "description": "Ecosystem benefit (0-1)"},
                        "infrastructure_benefit": {"type": "number", "description": "Infrastructure resilience benefit (0-1)"},
                        "policy_alignment": {"type": "number", "description": "Policy coherence/support (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["atmospheric_benefit", "ecological_benefit", "infrastructure_benefit", "policy_alignment"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "legal_precedent_seeding",
                "description": "CONFLUENCE: Spots windows when socio-political climate, institutional capacity, statutory ambiguity, and circuit splits align for favorable case law establishment.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "socio_political_climate": {"type": "number", "description": "Receptiveness to legal change (0-1)"},
                        "institutional_capacity": {"type": "number", "description": "Courts/resources to handle case (0-1)"},
                        "statutory_ambiguity": {"type": "number", "description": "Statutory text ambiguity/openness (0-1)"},
                        "circuit_split": {"type": "number", "description": "Degree of circuit split (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["socio_political_climate", "institutional_capacity", "statutory_ambiguity", "circuit_split"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "military_strategic_initiative",
                "description": "CONFLUENCE: Identifies decisive action opportunities when intelligence ambiguity, positional advantage, logistic readiness, and political authorization synchronize.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "enemy_ambiguity": {"type": "number", "description": "Intelligence gaps favoring surprise (0-1)"},
                        "positional_advantage": {"type": "number", "description": "Geographical/tactical position (0-1)"},
                        "logistic_readiness": {"type": "number", "description": "Sustainment capability ready (0-1)"},
                        "authorization_clarity": {"type": "number", "description": "Political authority clear (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["enemy_ambiguity", "positional_advantage", "logistic_readiness", "authorization_clarity"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "social_catalytic_alignment",
                "description": "CONFLUENCE: Spots transformative potential when individual readiness, network bridges, policy windows, and paradigm momentum converge.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "individual_readiness": {"type": "number", "description": "Population psychological readiness (0-1)"},
                        "network_bridges": {"type": "number", "description": "Cross-cutting network connections (0-1)"},
                        "policy_window": {"type": "number", "description": "Policy opportunity open (0-1)"},
                        "paradigm_momentum": {"type": "number", "description": "Cultural paradigm shift underway (0-1)"},
                        "f_time": {"type": "number", "default": 1.0}
                    },
                    "required": ["individual_readiness", "network_bridges", "policy_window", "paradigm_momentum"]
                }
            }
        }
    ]

    # Add bounded override params to all tools (optional)
    for tool in friction_tools + emergence_tools:
        tool["function"]["parameters"]["properties"].update(OVERRIDE_PROPERTIES)

    return friction_tools + emergence_tools


def execute_tool(tool_name, arguments):
    """
    Execute a Mantic tool by name with given arguments.
    
    Args:
        tool_name: Name of the tool to execute
        arguments: Dict of arguments to pass to the tool
    
    Returns:
        dict: Tool execution result
    
    Raises:
        ValueError: If tool_name is not recognized
    """
    if tool_name not in TOOL_MAP:
        raise ValueError(f"Unknown tool: {tool_name}. Available: {list(TOOL_MAP.keys())}")
    
    # Filter arguments to only those expected by the function
    func = TOOL_MAP[tool_name]
    import inspect
    sig = inspect.signature(func)
    valid_params = set(sig.parameters.keys())
    
    filtered_args = {k: v for k, v in arguments.items() if k in valid_params}
    
    return func(**filtered_args)


def get_tool_descriptions():
    """
    Get human-readable descriptions of all tools.
    
    Returns:
        dict: {tool_name: description}
    """
    tools = get_openai_tools()
    return {
        t["function"]["name"]: t["function"]["description"]
        for t in tools
    }


def get_tools_by_type(tool_type="all"):
    """
    Get tools filtered by type.
    
    Args:
        tool_type: "friction", "emergence", or "all"
    
    Returns:
        list: Filtered tool definitions
    """
    all_tools = get_openai_tools()
    
    if tool_type == "friction":
        return [t for t in all_tools if t["function"]["description"].startswith("FRICTION:")]
    elif tool_type == "emergence":
        return [t for t in all_tools if t["function"]["description"].startswith("CONFLUENCE:")]
    else:
        return all_tools


if __name__ == "__main__":
    # Test the adapter
    print("=== OpenAI Adapter Test (14 Tools) ===\n")
    
    tools = get_openai_tools()
    print(f"Total available tools: {len(tools)}")
    
    friction = get_tools_by_type("friction")
    emergence = get_tools_by_type("emergence")
    print(f"  Friction tools: {len(friction)}")
    print(f"  Emergence tools: {len(emergence)}")
    
    print("\n--- Testing Friction Tool ---")
    result = execute_tool("healthcare_phenotype_genotype", {
        "phenotypic": 0.3, "genomic": 0.9, "environmental": 0.4, "psychosocial": 0.8
    })
    print(f"Alert: {result['alert']}")
    print(f"M-Score: {result['m_score']:.3f}")
    
    print("\n--- Testing Emergence Tool ---")
    result = execute_tool("healthcare_precision_therapeutic", {
        "genomic_predisposition": 0.85, "environmental_readiness": 0.82,
        "phenotypic_timing": 0.88, "psychosocial_engagement": 0.90
    })
    print(f"Window Detected: {result['window_detected']}")
    print(f"Window Type: {result.get('window_type', 'N/A')}")
    print(f"M-Score: {result['m_score']:.3f}")
