"""Tests for MemoryTool20250818."""

import pytest
from pathlib import Path
from nanobot.agent.tools.anthropic import MemoryTool20250818
from nanobot.agent.tools.anthropic.base import CLIResult


@pytest.fixture
def temp_workspace(tmp_path):
    """Create temporary workspace."""
    return tmp_path


@pytest.fixture
def memory_tool(temp_workspace):
    """Create MemoryTool instance."""
    return MemoryTool20250818(workspace=temp_workspace)


def test_memory_tool_initialization(memory_tool, temp_workspace):
    """Test that MemoryTool initializes correctly."""
    assert memory_tool.api_type == "memory_20250818"
    assert memory_tool.name == "memory"
    assert memory_tool.beta_flag == "context-management-2025-06-27"
    assert (temp_workspace / "memories").exists()


def test_memory_tool_to_params(memory_tool):
    """Test that to_params returns correct format."""
    params = memory_tool.to_params()
    assert params == {
        "type": "memory_20250818",
        "name": "memory"
    }


@pytest.mark.asyncio
async def test_view_file(memory_tool, temp_workspace):
    """Test viewing a file with line numbers."""
    # Create test file
    test_file = temp_workspace / "memories" / "notes.txt"
    test_file.write_text("Line 1\nLine 2\nLine 3\n")

    result = await memory_tool(command="view", path="/memories/notes.txt")

    assert result.exit_code == 0
    assert result.error == ""
    assert "Here's the content of /memories/notes.txt with line numbers:" in result.output
    assert "     1\tLine 1" in result.output
    assert "     2\tLine 2" in result.output
    assert "     3\tLine 3" in result.output


@pytest.mark.asyncio
async def test_view_file_with_range(memory_tool, temp_workspace):
    """Test viewing a file with line range."""
    # Create test file with 10 lines
    test_file = temp_workspace / "memories" / "test.txt"
    test_file.write_text("\n".join([f"Line {i}" for i in range(1, 11)]))

    result = await memory_tool(command="view", path="/memories/test.txt", view_range=[3, 5])

    assert result.exit_code == 0
    assert "     3\tLine 3" in result.output
    assert "     4\tLine 4" in result.output
    assert "     5\tLine 5" in result.output
    assert "Line 1" not in result.output
    assert "Line 10" not in result.output


@pytest.mark.asyncio
async def test_view_file_not_exists(memory_tool):
    """Test viewing a nonexistent file."""
    result = await memory_tool(command="view", path="/memories/nonexistent.txt")

    assert result.exit_code == 1
    assert result.output == ""
    assert "The path /memories/nonexistent.txt does not exist" in result.error


@pytest.mark.asyncio
async def test_view_directory(memory_tool, temp_workspace):
    """Test viewing a directory listing."""
    # Create test directory structure
    memories = temp_workspace / "memories"
    (memories / "notes.txt").write_text("content")
    (memories / "project").mkdir()
    (memories / "project" / "status.xml").write_text("<status>ok</status>")
    (memories / ".hidden").write_text("hidden")  # Should be excluded

    result = await memory_tool(command="view", path="/memories")

    assert result.exit_code == 0
    assert result.error == ""
    assert "Here're the files and directories up to 2 levels deep in /memories" in result.output
    assert "/memories" in result.output
    assert "/memories/notes.txt" in result.output
    assert "/memories/project" in result.output
    assert "/memories/project/status.xml" in result.output
    assert ".hidden" not in result.output  # Hidden files excluded


@pytest.mark.asyncio
async def test_view_empty_directory(memory_tool):
    """Test viewing an empty directory."""
    result = await memory_tool(command="view", path="/memories")

    assert result.exit_code == 0
    assert "/memories" in result.output


@pytest.mark.asyncio
async def test_create_file(memory_tool, temp_workspace):
    """Test creating a new file."""
    result = await memory_tool(
        command="create",
        path="/memories/notes.txt",
        file_text="My notes\nLine 2\n"
    )

    assert result.exit_code == 0
    assert result.error == ""
    assert "File created successfully at: /memories/notes.txt" in result.output

    # Verify file was created
    created_file = temp_workspace / "memories" / "notes.txt"
    assert created_file.exists()
    assert created_file.read_text() == "My notes\nLine 2\n"


@pytest.mark.asyncio
async def test_create_file_nested_directory(memory_tool, temp_workspace):
    """Test creating a file in a nested directory (auto-creates parent dirs)."""
    result = await memory_tool(
        command="create",
        path="/memories/project/status.xml",
        file_text="<status>ok</status>"
    )

    assert result.exit_code == 0
    assert "File created successfully at: /memories/project/status.xml" in result.output

    # Verify file and parent directory were created
    created_file = temp_workspace / "memories" / "project" / "status.xml"
    assert created_file.exists()
    assert created_file.read_text() == "<status>ok</status>"


@pytest.mark.asyncio
async def test_create_file_already_exists(memory_tool, temp_workspace):
    """Test creating a file that already exists."""
    # Create file first
    existing = temp_workspace / "memories" / "existing.txt"
    existing.write_text("existing content")

    result = await memory_tool(
        command="create",
        path="/memories/existing.txt",
        file_text="new content"
    )

    assert result.exit_code == 1
    assert result.output == ""
    assert "Error: File /memories/existing.txt already exists" in result.error

    # Verify original content unchanged
    assert existing.read_text() == "existing content"


@pytest.mark.asyncio
async def test_create_file_missing_text(memory_tool):
    """Test creating a file without file_text parameter."""
    result = await memory_tool(
        command="create",
        path="/memories/notes.txt"
    )

    assert result.exit_code == 1
    assert result.output == ""
    assert "Error: file_text is required for create command" in result.error


@pytest.mark.asyncio
async def test_str_replace_success(memory_tool, temp_workspace):
    """Test replacing unique string in a file."""
    test_file = temp_workspace / "memories" / "config.txt"
    test_file.write_text("color: blue\nsize: large\n")

    result = await memory_tool(
        command="str_replace",
        path="/memories/config.txt",
        old_str="blue",
        new_str="green"
    )

    assert result.exit_code == 0
    assert result.error == ""
    assert "The memory file has been edited." in result.output

    # Verify file was modified
    assert test_file.read_text() == "color: green\nsize: large\n"


@pytest.mark.asyncio
async def test_str_replace_not_found(memory_tool, temp_workspace):
    """Test replacing string that doesn't exist."""
    test_file = temp_workspace / "memories" / "config.txt"
    test_file.write_text("color: blue\n")

    result = await memory_tool(
        command="str_replace",
        path="/memories/config.txt",
        old_str="red",
        new_str="green"
    )

    assert result.exit_code == 1
    assert result.output == ""
    assert "No replacement was performed, old_str `red` did not appear verbatim" in result.error


@pytest.mark.asyncio
async def test_str_replace_duplicate(memory_tool, temp_workspace):
    """Test replacing string that appears multiple times."""
    test_file = temp_workspace / "memories" / "config.txt"
    test_file.write_text("color: blue\nbackground: blue\n")

    result = await memory_tool(
        command="str_replace",
        path="/memories/config.txt",
        old_str="blue",
        new_str="green"
    )

    assert result.exit_code == 1
    assert result.output == ""
    assert "Multiple occurrences of old_str `blue`" in result.error
    assert "Please ensure it is unique" in result.error
