"""
Built-in tools for the OpenRouter Agent.
"""

import json
import os
from datetime import datetime
from typing import Any, Dict, Optional

from core.models import Tool


WORKING_DIRECTORY: Optional[str] = None


def set_working_directory(directory: Optional[str]) -> None:
    """Set the working directory for file operations"""
    global WORKING_DIRECTORY
    if directory is None:
        WORKING_DIRECTORY = None
    else:
        WORKING_DIRECTORY = os.path.abspath(directory)


def _resolve_path(path: str) -> str:
    """Resolve a path, prepending working directory if path is relative"""
    if os.path.isabs(path):
        return path
    if WORKING_DIRECTORY:
        return os.path.join(WORKING_DIRECTORY, path)
    return path


def get_current_time() -> str:
    """Returns current date and time as ISO format string"""
    return datetime.now().isoformat()


def calculate(expression: str) -> str:
    """Evaluate a mathematical expression safely"""
    try:
        allowed_chars = set("0123456789+-*/.() ")
        if not all(c in allowed_chars for c in expression):
            return "Error: Expression contains disallowed characters"
        
        result = eval(expression, {"__builtins__": {}}, {})
        return f"{expression} = {result}"
    except Exception as e:
        return f"Error evaluating expression: {str(e)}"


def read_file(file_path: str) -> str:
    """Read and return the contents of a file"""
    try:
        resolved_path = _resolve_path(file_path)
        with open(resolved_path, "r", encoding="utf-8") as file:
            return file.read()
    except FileNotFoundError:
        return f"Error: File not found: {file_path}"
    except PermissionError:
        return f"Error: Permission denied: {file_path}"
    except Exception as e:
        return f"Error reading file {file_path}: {str(e)}"


def write_file(file_path: str, content: str) -> str:
    """Write content to a file"""
    try:
        resolved_path = _resolve_path(file_path)
        with open(resolved_path, "w", encoding="utf-8") as file:
            file.write(content)
        return f"Successfully wrote to {file_path}"
    except PermissionError:
        return f"Error: Permission denied: {file_path}"
    except Exception as e:
        return f"Error writing to file {file_path}: {str(e)}"


def list_directory(directory_path: str) -> str:
    """List files and directories in a path"""
    try:
        resolved_path = _resolve_path(directory_path)
        entries = os.listdir(resolved_path)
        if not entries:
            return f"Directory is empty: {directory_path}"
        result = []
        for entry in entries:
            full_path = os.path.join(resolved_path, entry)
            if os.path.isdir(full_path):
                result.append(f"{entry}/")
            else:
                result.append(entry)
        return "\n".join(sorted(result))
    except FileNotFoundError:
        return f"Error: Directory not found: {directory_path}"
    except PermissionError:
        return f"Error: Permission denied: {directory_path}"
    except Exception as e:
        return f"Error listing directory {directory_path}: {str(e)}"


def file_exists(path: str) -> str:
    """Check if a file or directory exists"""
    resolved_path = _resolve_path(path)
    if os.path.exists(resolved_path):
        if os.path.isfile(resolved_path):
            return f"File exists: {path}"
        elif os.path.isdir(resolved_path):
            return f"Directory exists: {path}"
    return f"Path does not exist: {path}"


def ask_user(question: str) -> str:
    """Ask the user a question and return their response"""
    return f"[USER_INPUT_NEEDED]: {question}"


BUILTIN_TOOLS: Dict[str, Tool] = {
    "get_current_time": Tool(
        name="get_current_time",
        description="Get the current date and time",
        parameters={
            "type": "object",
            "properties": {},
            "required": []
        },
        function=get_current_time
    ),
    "calculate": Tool(
        name="calculate",
        description="Perform mathematical calculations",
        parameters={
            "type": "object",
            "properties": {
                "expression": {
                    "type": "string",
                    "description": "Mathematical expression to evaluate"
                }
            },
            "required": ["expression"]
        },
        function=calculate
    ),
    "read_file": Tool(
        name="read_file",
        description="Read the contents of a file",
        parameters={
            "type": "object",
            "properties": {
                "file_path": {
                    "type": "string",
                    "description": "The absolute path to the file to read"
                }
            },
            "required": ["file_path"]
        },
        function=read_file
    ),
    "write_file": Tool(
        name="write_file",
        description="Write content to a file",
        parameters={
            "type": "object",
            "properties": {
                "file_path": {
                    "type": "string",
                    "description": "The absolute path to the file to write"
                },
                "content": {
                    "type": "string",
                    "description": "The content to write to the file"
                }
            },
            "required": ["file_path", "content"]
        },
        function=write_file
    ),
    "list_directory": Tool(
        name="list_directory",
        description="List files and directories in a given path",
        parameters={
            "type": "object",
            "properties": {
                "directory_path": {
                    "type": "string",
                    "description": "The absolute path to the directory to list"
                }
            },
            "required": ["directory_path"]
        },
        function=list_directory
    ),
    "file_exists": Tool(
        name="file_exists",
        description="Check if a file or directory exists",
        parameters={
            "type": "object",
            "properties": {
                "path": {
                    "type": "string",
                    "description": "The absolute path to check"
                }
            },
            "required": ["path"]
        },
        function=file_exists
    ),
    "ask_user": Tool(
        name="ask_user",
        description="Ask the user a question and get their response",
        parameters={
            "type": "object",
            "properties": {
                "question": {
                    "type": "string",
                    "description": "The question to ask the user"
                }
            },
            "required": ["question"]
        },
        function=ask_user
    ),
}


def get_builtin_tools() -> Dict[str, Tool]:
    """Return a copy of the built-in tools dictionary"""
    return dict(BUILTIN_TOOLS)