"""List directory tool — show directory contents."""

from __future__ import annotations

from pathlib import Path
from typing import Any

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


class ListDirectoryTool(BaseTool):
    """List files and directories in a given path."""

    def spec(self) -> ToolSpec:
        return ToolSpec(
            name="list_directory",
            description=(
                "List files and directories in the specified path. "
                "Shows file type indicators: [DIR] for directories, "
                "[FILE] for files, with file sizes."
            ),
            parameters={
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "description": "Directory path to list. Default: current directory",
                    },
                },
                "required": [],
            },
            permission=PermissionLevel.READ,
        )

    def execute(self, **kwargs: Any) -> str:
        target = Path(kwargs.get("path", ".")).resolve()

        if not target.exists():
            return f"Error: Path not found: {target}"
        if not target.is_dir():
            return f"Error: Not a directory: {target}"

        try:
            entries = sorted(target.iterdir(), key=lambda p: (not p.is_dir(), p.name.lower()))
        except PermissionError:
            return f"Error: Permission denied: {target}"

        if not entries:
            return f"Directory is empty: {target}"

        lines = [f"Contents of {target}:"]
        for entry in entries[:500]:
            if entry.is_dir():
                lines.append(f"  [DIR]  {entry.name}/")
            else:
                try:
                    size = entry.stat().st_size
                    if size < 1024:
                        size_str = f"{size} B"
                    elif size < 1024 * 1024:
                        size_str = f"{size / 1024:.1f} KB"
                    else:
                        size_str = f"{size / (1024 * 1024):.1f} MB"
                    lines.append(f"  [FILE] {entry.name}  ({size_str})")
                except OSError:
                    lines.append(f"  [FILE] {entry.name}")

        if len(entries) > 500:
            lines.append(f"  ... and {len(entries) - 500} more entries")

        return "\n".join(lines)
