#!/usr/bin/env python3
"""Planner Agent — Generated by ABI-Core"""

import json

from planner import AbiPlannerAgent
from abi_core.agent import AbiCore
from abi_core.common.utils import abi_logging, clean_llm_json
from abi_core.common.semantic_tools import (
    tool_find_agent,
    tool_recommend_agents,
    tool_search_tools,
)

agent = AbiCore()


@agent.task(
    name="analyze_query",
    input_map={
        "query": "$input.query",
        "context": "$input.context",
    },
)
async def analyze_query(query, context):
    """Prepare the planning prompt from query + context."""
    planning_query = f"User request: {query}\nContext: {json.dumps(context, indent=2)}"
    return {"planning_query": planning_query}


@agent.task(
    name="parse_plan",
    depends_on=["analyze_query"],
    input_map={"raw_response": "$input.llm_response"},
)
def parse_plan(raw_response):
    """Clean and parse the LLM response into structured plan data."""
    if not raw_response:
        return {"status": "error", "message": "Empty LLM response"}
    return clean_llm_json(raw_response)


@agent.task(
    name="assign_agents",
    depends_on=["parse_plan"],
    input_map={"plan_data": "$parse_plan"},
)
async def assign_agents(plan_data):
    """Assign agents or builder specs to each task in the plan.

    For each task:
    1. Search for an existing agent → type: "execute"
    2. No agent found → search tools in semantic layer
       - Tools found → type: "build_and_execute" (builder creates ephemeral agent)
       - No tools → type: "create_tools_and_execute" (builder creates tools first)
    """
    if plan_data.get("status") != "ready":
        return plan_data  # pass through clarification / error

    plan = plan_data.get("plan", {})
    tasks = plan.get("tasks", [])

    # Infrastructure agents that should never be assigned as task executors
    INFRA_AGENTS = {"builder", "planner", "orchestrator", "guardian", "semantic-layer"}

    abi_logging(f"[🔍] Assigning agents/tools to {len(tasks)} tasks...")

    for task in tasks:
        task_desc = task.get("description", "")
        task_id = task.get("task_id", "unknown")

        # Step 1: Try to find an existing agent
        found_agent = await tool_find_agent.ainvoke(task_desc)

        if found_agent:
            agent_name = (
                found_agent.name if hasattr(found_agent, "name") else
                found_agent.get("name", "") if isinstance(found_agent, dict) else ""
            ).lower()
            # Skip infrastructure agents — they are not task executors
            if any(infra in agent_name for infra in INFRA_AGENTS):
                abi_logging(
                    f"[⚠️] Task '{task_id}': found '{agent_name}' but it's infrastructure, skipping"
                )
                found_agent = None

        if found_agent:
            agent_data = found_agent.dict() if hasattr(found_agent, "dict") else found_agent
            task["type"] = "execute"
            task["agents"] = [agent_data]
            abi_logging(f"[✅] Task '{task_id}': agent found → execute")
            continue

        # Step 2: No agent — search for tools in semantic layer
        matching_tools = await tool_search_tools.ainvoke(task_desc)

        if matching_tools:
            tool_names = [t["name"] for t in matching_tools]
            task["type"] = "build_and_execute"
            task["agents"] = []
            task["builder_spec"] = {
                "system_prompt": (
                    f"You are a specialized agent for: {task_desc}. "
                    f"Use the available tools to complete the task."
                ),
                "tools": tool_names,
                "tools_detail": matching_tools,
                "ephemeral": True,
            }
            abi_logging(
                f"[🔧] Task '{task_id}': no agent, {len(tool_names)} tools found "
                f"→ build_and_execute"
            )
            continue

        # Step 3: No agent, no tools — builder must create everything
        task["type"] = "create_tools_and_execute"
        task["agents"] = []
        task["builder_spec"] = {
            "system_prompt": (
                f"You are a specialized agent for: {task_desc}. "
                f"Complete the task using the tools provided."
            ),
            "tools_to_create": [
                {
                    "tool_name": f"{task_id}_tool",
                    "objective": task_desc,
                    "constraints": "",
                    "edge_cases": [],
                    "description": f"Tool for: {task_desc}",
                    "parameters": {},
                    "implementation_hints": "",
                    "metadata": {},
                }
            ],
            "ephemeral": True,
        }
        abi_logging(
            f"[🏗️] Task '{task_id}': no agent, no tools → create_tools_and_execute"
        )

    return plan_data


agent.run(AbiPlannerAgent())
