"""Tests for launcher.skills._project_detector module."""

from __future__ import annotations

import json
from pathlib import Path


class TestDetectProject:
    """Test project technology detection."""

    def test_detects_typescript_from_package_json(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "package.json").write_text(json.dumps({"name": "my-app", "dependencies": {"react": "^18"}}))
        (tmp_path / "tsconfig.json").write_text("{}")

        result = detect_project(tmp_path)
        assert "TypeScript" in result["languages"]
        assert "React" in result["frameworks"]
        assert result["name"] == "my-app"

    def test_detects_javascript_without_tsconfig(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "package.json").write_text(json.dumps({"name": "js-app", "dependencies": {"express": "^4"}}))

        result = detect_project(tmp_path)
        assert "JavaScript" in result["languages"]
        assert "Express" in result["frameworks"]

    def test_detects_python_from_pyproject(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "pyproject.toml").write_text('[project]\nname = "my-lib"\ndependencies = ["fastapi", "pytest"]')

        result = detect_project(tmp_path)
        assert "Python" in result["languages"]
        assert "FastAPI" in result["frameworks"]
        assert "pytest" in result["test_frameworks"]

    def test_detects_go_from_go_mod(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "go.mod").write_text("module github.com/user/myservice\n\ngo 1.22\n")

        result = detect_project(tmp_path)
        assert "Go" in result["languages"]
        assert result["name"] == "myservice"

    def test_detects_rust_from_cargo(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "Cargo.toml").write_text('[package]\nname = "my-crate"\nversion = "0.1.0"\n')

        result = detect_project(tmp_path)
        assert "Rust" in result["languages"]
        assert result["name"] == "my-crate"

    def test_detects_package_manager_bun(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "package.json").write_text('{"name": "app"}')
        (tmp_path / "bun.lockb").write_text("")

        result = detect_project(tmp_path)
        assert result["package_manager"] == "bun"

    def test_detects_package_manager_pnpm(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "package.json").write_text('{"name": "app"}')
        (tmp_path / "pnpm-lock.yaml").write_text("")

        result = detect_project(tmp_path)
        assert result["package_manager"] == "pnpm"

    def test_detects_package_manager_uv(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "pyproject.toml").write_text('[project]\nname = "app"\n')
        (tmp_path / "uv.lock").write_text("")

        result = detect_project(tmp_path)
        assert result["package_manager"] == "uv"

    def test_detects_dev_commands(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "package.json").write_text(
            json.dumps(
                {
                    "name": "app",
                    "scripts": {"dev": "vite", "build": "tsc && vite build", "test": "vitest"},
                }
            )
        )

        result = detect_project(tmp_path)
        assert result["dev_commands"]["dev"] == "vite"
        assert result["dev_commands"]["build"] == "tsc && vite build"
        assert result["dev_commands"]["test"] == "vitest"

    def test_handles_missing_files(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        result = detect_project(tmp_path)
        assert result["name"] == tmp_path.name
        assert result["languages"] == []
        assert result["frameworks"] == []

    def test_detects_directory_structure(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "src").mkdir()
        (tmp_path / "tests").mkdir()
        (tmp_path / "node_modules").mkdir()  # should be skipped
        (tmp_path / ".git").mkdir()  # should be skipped

        result = detect_project(tmp_path)
        assert "src" in result["directory_structure"]
        assert "tests" in result["directory_structure"]
        assert "node_modules" not in result["directory_structure"]
        assert ".git" not in result["directory_structure"]

    def test_polyglot_project(self, tmp_path: Path):
        from launcher.skills._project_detector import detect_project

        (tmp_path / "package.json").write_text(json.dumps({"name": "fullstack", "dependencies": {"next": "^14"}}))
        (tmp_path / "tsconfig.json").write_text("{}")
        (tmp_path / "pyproject.toml").write_text('[project]\nname = "fullstack"\ndependencies = ["fastapi"]')

        result = detect_project(tmp_path)
        assert "TypeScript" in result["languages"]
        assert "Python" in result["languages"]
        assert "Next.js" in result["frameworks"]
        assert "FastAPI" in result["frameworks"]
