from pathlib import Path

import pytest

from gjalla_precommit.tools import search_tools


def test_read_file_with_fallback_uses_latin1(tmp_path: Path) -> None:
    test_file = tmp_path / "latin1.txt"
    test_file.write_bytes(b"\xff")

    content = search_tools._read_file_with_fallback(test_file)

    assert content == "\xff"


@pytest.mark.asyncio
async def test_grep_invalid_regex_returns_error(tmp_path: Path) -> None:
    result = await search_tools.grep("[invalid", repo_root=tmp_path)

    assert not result.success
    assert "invalid regex" in result.error.lower()


@pytest.mark.asyncio
async def test_grep_rejects_path_traversal(tmp_path: Path) -> None:
    result = await search_tools.grep("match", repo_root=tmp_path, path="../outside.txt")

    assert not result.success
    assert "path traversal" in result.error.lower()


@pytest.mark.asyncio
async def test_grep_binary_file_returns_empty_results(tmp_path: Path) -> None:
    binary_file = tmp_path / "binary.bin"
    binary_file.write_bytes(b"\x00\xff\x00\xff")

    result = await search_tools.grep("match", repo_root=tmp_path, path="binary.bin")

    assert result.success
    assert result.data == []


@pytest.mark.asyncio
async def test_grep_file_too_large_returns_error(tmp_path: Path) -> None:
    large_file = tmp_path / "large.txt"
    large_file.write_bytes(b"a" * (search_tools.MAX_FILE_SIZE + 1))

    result = await search_tools.grep("a", repo_root=tmp_path, path="large.txt")

    assert not result.success
    assert "too large" in result.error.lower()


@pytest.mark.asyncio
async def test_grep_directory_skips_hidden_and_skip_dirs(tmp_path: Path) -> None:
    (tmp_path / "src").mkdir()
    (tmp_path / "node_modules").mkdir()
    (tmp_path / ".git").mkdir()

    (tmp_path / "src" / "app.py").write_text("match_me", encoding="utf-8")
    (tmp_path / "node_modules" / "skip.js").write_text("match_me", encoding="utf-8")
    (tmp_path / ".git" / "skip.txt").write_text("match_me", encoding="utf-8")

    result = await search_tools.grep("match_me", repo_root=tmp_path, path=".")

    assert result.success
    assert any("app.py" in match and "src" in match for match in result.data)
    assert not any("node_modules" in match for match in result.data)
    assert not any(".git" in match for match in result.data)


