"""
Lab 2.8: Multi-Tool Agent -- SOLUTION

Agent with file operations AND web search capabilities.
Uses Anthropic API with three tools, or mock for offline execution.
"""

import json
import os
import sys

sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '_shared'))
try:
    from mock_llm import MockAnthropic as Anthropic
    client = Anthropic()
    IS_MOCK = True
except ImportError:
    from anthropic import Anthropic
    client = Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
    IS_MOCK = False

MAX_ITERATIONS = 15

TOOLS = [
    {
        "name": "read_file",
        "description": "Read the contents of a file at the given path",
        "input_schema": {
            "type": "object",
            "properties": {
                "path": {"type": "string", "description": "Path to the file"},
                "reasoning": {"type": "string", "description": "Why are you reading this?"}
            },
            "required": ["path", "reasoning"]
        }
    },
    {
        "name": "search_web",
        "description": "Search the web for current information. Returns a summary of results.",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "The search query"},
                "reasoning": {"type": "string", "description": "Why are you searching?"}
            },
            "required": ["query", "reasoning"]
        }
    },
    {
        "name": "write_file",
        "description": "Write content to a file at the given path",
        "input_schema": {
            "type": "object",
            "properties": {
                "path": {"type": "string", "description": "Path to write to"},
                "content": {"type": "string", "description": "Content to write"},
                "reasoning": {"type": "string", "description": "Why are you writing this?"}
            },
            "required": ["path", "content", "reasoning"]
        }
    }
]


def execute_tool(tool_name: str, tool_args: dict) -> str:
    if tool_name == "read_file":
        path = tool_args["path"]
        try:
            with open(path, "r") as f:
                return f"Contents of {path}:\n{f.read()}"
        except FileNotFoundError:
            return f"Error: File not found at {path}"
        except Exception as e:
            return f"Error: {str(e)}"
    
    elif tool_name == "search_web":
        query = tool_args["query"]
        try:
            import urllib.request
            import urllib.parse
            encoded = urllib.parse.quote(query)
            url = f"https://api.duckduckgo.com/?q={encoded}&format=json"
            with urllib.request.urlopen(url, timeout=10) as resp:
                data = json.loads(resp.read())
                summary = data.get("AbstractText", "")
                results = data.get("RelatedTopics", [])[:3]
                result_texts = [r.get("Text", "") for r in results if isinstance(r, dict)]
                parts = [f"Summary: {summary}" if summary else ""] + result_texts
                return "\n".join(parts) if any(parts) else "No results found."
        except Exception as e:
            return f"Search failed: {str(e)}. Try manual search."
    
    elif tool_name == "write_file":
        path = tool_args["path"]
        content = tool_args["content"]
        try:
            os.makedirs(os.path.dirname(path) or ".", exist_ok=True)
            with open(path, "w") as f:
                f.write(content)
            return f"Successfully wrote {len(content)} bytes to {path}"
        except Exception as e:
            return f"Error writing file: {str(e)}"
    
    return f"Unknown tool: {tool_name}"


def run_agent(prompt: str) -> str:
    """Run multi-tool agent loop. Works with real API or mock."""
    
    system_prompt = """You are a helpful assistant with access to file operations and web search.
You can read files, search the web, and write files.
Combine tools as needed to fulfill the user's request."""
    
    messages = [{"role": "user", "content": prompt}]
    
    for _ in range(MAX_ITERATIONS):
        response = client.messages.create(
            model="claude-sonnet-4-20260501" if not IS_MOCK else "mock-model",
            max_tokens=4096,
            system=system_prompt,
            messages=messages,
            tools=TOOLS
        )
        
        if response.stop_reason == "tool_use":
            for block in response.content:
                if block.type == "tool_use":
                    result = execute_tool(block.name, block.input)
                    messages.append({"role": "assistant", "content": response.content})
                    messages.append({"role": "user", "content": result})
        elif response.stop_reason == "end_turn":
            return "".join(b.text for b in response.content if b.type == "text")
        else:
            return f"Unexpected: {response.stop_reason}"
    
    return "Max iterations reached."


if __name__ == "__main__":
    prompt = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "Search for recent AI agent news and save the results to research.txt"
    print(run_agent(prompt))
