"""push で送るファイルの選別のテスト（SPEC_03「push」）.

`.git/`・`.venv/`・`__pycache__/`・`.pytest_cache/`・`.ruff_cache/` はどこにあっても送らない．
`data/`・`runs/`・`.claude/` はプロジェクト直下のみ除外する（`src/tias_judge_model/data/`・
`tests/data/` は送る）．
"""

from __future__ import annotations

from pathlib import Path

import pytest

from tias_judge_model.remote.files import collect_push_entries, is_excluded

SENT = [
    "pyproject.toml",
    "uv.lock",
    ".python-version",
    "src/tias_judge_model/__init__.py",
    "src/tias_judge_model/data/manifest.py",
    "src/tias_judge_model/remote/gpu.py",
    "tests/data/test_split.py",
    "tests/remote/test_gpu.py",
    "scripts/make_synthetic_dataset.py",
    "configs/remote.yaml",
]

NOT_SENT = [
    ".git/config",
    ".git/objects/ab/cdef",
    ".venv/Scripts/python.exe",
    "__pycache__/x.pyc",
    "src/tias_judge_model/__pycache__/a.cpython-312.pyc",
    "tests/data/__pycache__/b.pyc",
    ".pytest_cache/v/cache/nodeids",
    ".ruff_cache/0.1/x",
    "data/synthetic/manifest.csv",
    "data/synthetic/images/pale_1/P0001.png",
    "runs/20260927-120000_x/metrics.json",
    "runs/_remote_logs/exp1.log",
    ".claude/settings.json",
    ".claude/rules/testing.md",
]


def _make_tree(root: Path, paths: list[str]) -> None:
    for rel in paths:
        path = root / rel
        path.parent.mkdir(parents=True, exist_ok=True)
        path.write_bytes(b"x")


def test_collect_push_entries_excludes_listed_directories(tmp_path: Path) -> None:
    _make_tree(tmp_path, SENT + NOT_SENT)
    arcnames = [entry.arcname for entry in collect_push_entries(tmp_path)]
    assert sorted(arcnames) == sorted(SENT)


def test_arcnames_are_posix_relative(tmp_path: Path) -> None:
    _make_tree(tmp_path, ["src/tias_judge_model/data/manifest.py"])
    entries = collect_push_entries(tmp_path)
    assert [e.arcname for e in entries] == ["src/tias_judge_model/data/manifest.py"]
    assert entries[0].size == 1


@pytest.mark.parametrize("rel", NOT_SENT)
def test_is_excluded_for_not_sent(rel: str) -> None:
    assert is_excluded(rel)


@pytest.mark.parametrize("rel", SENT)
def test_is_not_excluded_for_sent(rel: str) -> None:
    assert not is_excluded(rel)


@pytest.mark.parametrize("rel", ["data", "runs", ".claude", ".git", ".venv"])
def test_root_directories_themselves_are_excluded(rel: str) -> None:
    assert is_excluded(rel)


@pytest.mark.parametrize(
    "rel", ["src/tias_judge_model/data", "tests/data", "src/tias_judge_model/runs_util.py"]
)
def test_nested_data_is_not_excluded(rel: str) -> None:
    assert not is_excluded(rel)
