"""Read file tool — reads file contents with optional line range."""

from __future__ import annotations

from pathlib import Path
from typing import Any

from tsumugi.tools.base import BaseTool, PermissionLevel, ToolSpec


class ReadFileTool(BaseTool):
    """Read file contents, optionally with line offset and limit."""

    def spec(self) -> ToolSpec:
        return ToolSpec(
            name="read_file",
            description=(
                "Read the contents of a file. "
                "Returns the file content with line numbers. "
                "Use offset and limit for large files."
            ),
            parameters={
                "type": "object",
                "properties": {
                    "file_path": {
                        "type": "string",
                        "description": "Absolute or relative path to the file",
                    },
                    "offset": {
                        "type": "integer",
                        "description": "Line number to start from (1-based). Default: 1",
                    },
                    "limit": {
                        "type": "integer",
                        "description": "Max number of lines to read. Default: 2000",
                    },
                },
                "required": ["file_path"],
            },
            permission=PermissionLevel.READ,
        )

    def execute(self, **kwargs: Any) -> str:
        file_path = kwargs["file_path"]
        offset = kwargs.get("offset", 1)
        limit = kwargs.get("limit", 2000)

        path = Path(file_path).resolve()
        if not path.exists():
            return f"Error: File not found: {path}"
        if not path.is_file():
            return f"Error: Not a file: {path}"

        try:
            text = path.read_text(encoding="utf-8", errors="replace")
        except OSError as e:
            return f"Error reading file: {e}"

        lines = text.splitlines()
        total = len(lines)

        # Apply offset (1-based) and limit
        start = max(0, offset - 1)
        end = min(total, start + limit)
        selected = lines[start:end]

        # Format with line numbers
        result_lines = []
        for i, line in enumerate(selected, start=start + 1):
            # Truncate very long lines
            if len(line) > 2000:
                line = line[:2000] + "... (truncated)"
            result_lines.append(f"{i:>6}\t{line}")

        header = f"File: {path} ({total} lines total)"
        if start > 0 or end < total:
            header += f", showing lines {start + 1}-{end}"

        return header + "\n" + "\n".join(result_lines)
