"""Test that bash tool handles heredoc commands correctly.

Reproduces the bug where `; echo '<<exit>>'` appended on the same line
as a heredoc terminator prevents bash from recognizing the terminator,
causing the session to hang forever.
"""

import asyncio
import pytest
from nanobot.agent.tools.anthropic.bash import BashTool20250124


@pytest.mark.asyncio
async def test_heredoc_command():
    """Heredoc commands must complete without hanging."""
    tool = BashTool20250124()

    # Simple command works
    result = await tool(command="echo hello")
    assert result.output == "hello"

    # Heredoc command — this is the exact pattern that caused the hang
    result = await asyncio.wait_for(
        tool(command="cat << 'EOF'\nline1\nline2\nEOF"),
        timeout=5.0,
    )
    assert "line1" in result.output
    assert "line2" in result.output


@pytest.mark.asyncio
async def test_heredoc_append_to_file():
    """Heredoc append (the exact pattern the LLM uses) must work."""
    tool = BashTool20250124()

    result = await asyncio.wait_for(
        tool(command="cat >> /tmp/test_heredoc_bash.txt << 'EOF'\nhello world\nEOF"),
        timeout=5.0,
    )
    # Should complete without error
    assert result.error is None or result.error == ""

    # Verify the file was written
    result2 = await tool(command="cat /tmp/test_heredoc_bash.txt")
    assert "hello world" in result2.output

    # Cleanup
    await tool(command="rm -f /tmp/test_heredoc_bash.txt")


@pytest.mark.asyncio
async def test_regular_commands_still_work():
    """Ensure regular commands still work after the fix."""
    tool = BashTool20250124()

    # Semicolons in commands
    result = await tool(command="echo a; echo b")
    assert "a" in result.output
    assert "b" in result.output

    # Multiline script
    result = await tool(command="for i in 1 2 3; do echo $i; done")
    assert "1" in result.output
    assert "3" in result.output

    # Command with exit code
    result = await tool(command="true")
    assert result.output == "(no output)" or result.output is not None
