"""Tests for PROJECT_NAMES auto-detection from config."""

import os
import textwrap

from neo_cortex.config import _detect_project_names


def test_explicit_override(monkeypatch, tmp_path):
    """PROJECT_NAMES env var overrides all detection."""
    monkeypatch.setenv("PROJECT_NAMES", "alpha,beta,gamma")
    monkeypatch.setattr("neo_cortex.config._data_dir", str(tmp_path))
    result = _detect_project_names()
    assert result == ["alpha", "beta", "gamma"]


def test_explicit_strips_whitespace(monkeypatch, tmp_path):
    """PROJECT_NAMES handles spaces around commas."""
    monkeypatch.setenv("PROJECT_NAMES", " foo , bar , baz ")
    monkeypatch.setattr("neo_cortex.config._data_dir", str(tmp_path))
    result = _detect_project_names()
    assert result == ["foo", "bar", "baz"]


def test_gitmodules_detection(monkeypatch, tmp_path):
    """Reads submodule names from .gitmodules."""
    monkeypatch.delenv("PROJECT_NAMES", raising=False)
    gitmodules = tmp_path / ".gitmodules"
    gitmodules.write_text(textwrap.dedent("""\
        [submodule "backend"]
            path = backend
            url = https://github.com/org/backend.git
        [submodule "frontend"]
            path = frontend
            url = https://github.com/org/frontend.git
    """))
    monkeypatch.setattr("neo_cortex.config._data_dir", str(tmp_path))
    result = _detect_project_names()
    # Root dir first, then submodules sorted
    root = tmp_path.name
    assert result[0] == root
    assert "backend" in result
    assert "frontend" in result


def test_gitmodules_skips_dotfiles(monkeypatch, tmp_path):
    """Submodules starting with . are excluded."""
    monkeypatch.delenv("PROJECT_NAMES", raising=False)
    gitmodules = tmp_path / ".gitmodules"
    gitmodules.write_text(textwrap.dedent("""\
        [submodule ".hidden"]
            path = .hidden
            url = https://github.com/org/hidden.git
        [submodule "visible"]
            path = visible
            url = https://github.com/org/visible.git
    """))
    monkeypatch.setattr("neo_cortex.config._data_dir", str(tmp_path))
    result = _detect_project_names()
    assert ".hidden" not in result
    assert "visible" in result


def test_root_project_always_first(monkeypatch, tmp_path):
    """Root directory name is always first in the list."""
    monkeypatch.delenv("PROJECT_NAMES", raising=False)
    gitmodules = tmp_path / ".gitmodules"
    gitmodules.write_text(textwrap.dedent("""\
        [submodule "aaa-first-alphabetically"]
            path = aaa-first-alphabetically
            url = https://example.com/aaa.git
    """))
    monkeypatch.setattr("neo_cortex.config._data_dir", str(tmp_path))
    result = _detect_project_names()
    root = tmp_path.name
    assert result[0] == root
    assert result[1] == "aaa-first-alphabetically"


def test_subdirs_with_git(monkeypatch, tmp_path):
    """Detects standalone repos (dirs with .git) when no .gitmodules."""
    monkeypatch.delenv("PROJECT_NAMES", raising=False)
    # Create subdirs with .git
    (tmp_path / "project-a" / ".git").mkdir(parents=True)
    (tmp_path / "project-b" / ".git").mkdir(parents=True)
    (tmp_path / "not-a-repo").mkdir()  # no .git — should be excluded
    monkeypatch.setattr("neo_cortex.config._data_dir", str(tmp_path))
    result = _detect_project_names()
    root = tmp_path.name
    assert result[0] == root
    assert "project-a" in result
    assert "project-b" in result
    assert "not-a-repo" not in result


def test_fallback_to_basename(monkeypatch, tmp_path):
    """No .gitmodules, no git subdirs — uses directory basename."""
    monkeypatch.delenv("PROJECT_NAMES", raising=False)
    monkeypatch.setattr("neo_cortex.config._data_dir", str(tmp_path))
    result = _detect_project_names()
    assert result == [tmp_path.name]


def test_empty_explicit_falls_through(monkeypatch, tmp_path):
    """Empty PROJECT_NAMES env var triggers auto-detection."""
    monkeypatch.setenv("PROJECT_NAMES", "  ")
    monkeypatch.setattr("neo_cortex.config._data_dir", str(tmp_path))
    result = _detect_project_names()
    # Should fall through to auto-detection, not return empty
    assert len(result) >= 1
