"""Extended tests for project.py: get_project_description, cleanup_stale_mcp."""

from pathlib import Path

import project


class TestGetProjectDescription:
    def test_extracts_from_vision_section(self, tmp_path: Path):
        scope = tmp_path / ".autobuilder" / "scope.md"
        scope.parent.mkdir(parents=True)
        scope.write_text(
            "# Project\n\n## Vision\nA trading platform for retail investors. "
            "It has charts.\n\n## Other\nStuff.\n"
        )
        result = project.get_project_description(tmp_path)
        assert "A trading platform for retail investors" in result

    def test_returns_empty_when_no_scope(self, tmp_path: Path):
        assert project.get_project_description(tmp_path) == ""

    def test_returns_empty_when_no_vision_section(self, tmp_path: Path):
        scope = tmp_path / ".autobuilder" / "scope.md"
        scope.parent.mkdir(parents=True)
        scope.write_text("# Project\n\nSome text.\n")
        assert project.get_project_description(tmp_path) == ""

    def test_stops_at_next_heading(self, tmp_path: Path):
        scope = tmp_path / ".autobuilder" / "scope.md"
        scope.parent.mkdir(parents=True)
        scope.write_text("## Vision\nFirst sentence. More text.\n## Other\n")
        result = project.get_project_description(tmp_path)
        assert result == "First sentence"

    def test_strips_trailing_dot(self, tmp_path: Path):
        scope = tmp_path / ".autobuilder" / "scope.md"
        scope.parent.mkdir(parents=True)
        scope.write_text("## Vision\nJust one sentence.\n")
        result = project.get_project_description(tmp_path)
        assert not result.endswith(".")

    def test_skips_blank_lines_in_vision(self, tmp_path: Path):
        scope = tmp_path / ".autobuilder" / "scope.md"
        scope.parent.mkdir(parents=True)
        scope.write_text("## Vision\n\nThe actual description.\n")
        result = project.get_project_description(tmp_path)
        assert "actual description" in result


class TestCleanupStaleMcp:
    def test_removes_mcp_json(self, project_dir: Path):
        mcp = project_dir / ".cursor" / "mcp.json"
        mcp.parent.mkdir(parents=True)
        mcp.write_text('{"some": "config"}')
        project.cleanup_stale_mcp(project_dir)
        assert not mcp.exists()

    def test_noop_when_no_mcp(self, project_dir: Path):
        project.cleanup_stale_mcp(project_dir)

    def test_handles_permission_error(self, project_dir: Path, monkeypatch):
        mcp = project_dir / ".cursor" / "mcp.json"
        mcp.parent.mkdir(parents=True)
        mcp.write_text("{}")

        def fail_unlink(*args, **kwargs):
            raise PermissionError("denied")

        monkeypatch.setattr(Path, "unlink", fail_unlink)
        project.cleanup_stale_mcp(project_dir)


class TestConsumeBacklogAtomicity:
    def test_atomically_consumes(self, tmp_path: Path):
        bl = tmp_path / "backlog.md"
        bl.write_text("Fix the login page")
        result = project.consume_backlog(bl)
        assert result == "Fix the login page"
        assert not bl.exists()
        assert not bl.with_name("backlog.processing.md").exists()

    def test_strips_whitespace(self, tmp_path: Path):
        bl = tmp_path / "backlog.md"
        bl.write_text("  \n  Fix this  \n  ")
        result = project.consume_backlog(bl)
        assert result == "Fix this"


class TestSyncSkillsReplacesDirWithSymlink:
    def test_replaces_existing_dir(self, project_dir: Path):
        target = project_dir / ".cursor" / "skills" / "autobuilder"
        target.mkdir(parents=True)
        (target / "stale-file").write_text("old")

        result = project.sync_skills_to_project(project_dir)
        assert result is True
        assert target.is_symlink()

    def test_replaces_stale_symlink(self, project_dir: Path):
        target = project_dir / ".cursor" / "skills" / "autobuilder"
        target.parent.mkdir(parents=True, exist_ok=True)
        target.symlink_to("/tmp/nonexistent-path")

        result = project.sync_skills_to_project(project_dir)
        assert result is True
        assert target.is_symlink()
        assert target.resolve() != Path("/tmp/nonexistent-path")
