"""
test_add_team.py

scripts/add-team.py 단위 테스트 (아르고스 작성)

테스트 항목:
- load_config(): teams.json 로드, 파일 없을 때 기본값 반환
- save_config(): 파일 저장, 메타데이터 자동 계산, updated 타임스탬프 설정
- generate_team_id(): 한글→영문 변환, 특수문자 제거, 소문자 처리
- create_team_directory(): 팀 디렉터리 및 기본 파일 생성
- add_team(): 팀 추가, 중복 검사, config 저장, 디렉터리 생성
- list_teams(): 팀 목록 출력, 빈 목록 메시지
- main(): CLI 인수 파싱, --list, --name/--type 필수 검사

격리: monkeypatch로 _mod.CONFIG_FILE 과 _mod.TEAMS_DIR 을 tmp_path로 교체
"""

import importlib.util
import json
import os
import sys
from datetime import datetime
from pathlib import Path

import pytest

# ---------------------------------------------------------------------------
# 모듈 로드 (하이픈 포함 파일명 → importlib 필요)
# ---------------------------------------------------------------------------

_WORKSPACE = Path(os.environ.get("WORKSPACE_ROOT", "/home/jay/workspace"))
_SCRIPT_PATH = _WORKSPACE / "scripts" / "add-team.py"


def _load_module():
    """add-team.py를 importlib로 로드하여 반환"""
    spec = importlib.util.spec_from_file_location("add_team", _SCRIPT_PATH)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module


_mod = _load_module()

# ---------------------------------------------------------------------------
# 공통 fixture
# ---------------------------------------------------------------------------

_SAMPLE_CONFIG = {
    "version": "1.0",
    "updated": "2026-03-02 04:05:57",
    "teams": {
        "dev1-team": {
            "name": "개발1팀",
            "type": "수직조직",
            "status": "active",
            "lead": "hermes",
            "members": ["vulcan", "iris", "athena", "argos"],
        }
    },
    "metadata": {
        "total_teams": 1,
        "active_teams": 1,
        "planned_teams": 0,
        "total_members": 4,
    },
}


@pytest.fixture()
def setup_config(tmp_path, monkeypatch):
    """tmp_path에 config/teams.json을 생성하고 모듈 전역 변수를 패치한다."""
    config_dir = tmp_path / "config"
    config_dir.mkdir()
    teams_dir = tmp_path / "teams"
    teams_dir.mkdir()

    config_file = config_dir / "teams.json"
    config_file.write_text(
        json.dumps(_SAMPLE_CONFIG, ensure_ascii=False, indent=2), encoding="utf-8"
    )

    monkeypatch.setattr(_mod, "CONFIG_FILE", config_file)
    monkeypatch.setattr(_mod, "TEAMS_DIR", teams_dir)

    yield tmp_path


@pytest.fixture()
def empty_config(tmp_path, monkeypatch):
    """빈 팀 목록을 가진 config를 생성하고 모듈 전역 변수를 패치한다."""
    config_dir = tmp_path / "config"
    config_dir.mkdir()
    teams_dir = tmp_path / "teams"
    teams_dir.mkdir()

    config_file = config_dir / "teams.json"
    empty = {"version": "1.0", "teams": {}, "metadata": {}}
    config_file.write_text(
        json.dumps(empty, ensure_ascii=False, indent=2), encoding="utf-8"
    )

    monkeypatch.setattr(_mod, "CONFIG_FILE", config_file)
    monkeypatch.setattr(_mod, "TEAMS_DIR", teams_dir)

    yield tmp_path


# ---------------------------------------------------------------------------
# TestLoadConfig
# ---------------------------------------------------------------------------


class TestLoadConfig:
    """load_config() 함수 테스트"""

    def test_load_config_from_file(self, setup_config):
        """기존 teams.json을 올바르게 로드한다"""
        config = _mod.load_config()
        assert config["version"] == "1.0"
        assert "dev1-team" in config["teams"]

    def test_load_config_missing_file(self, tmp_path, monkeypatch):
        """파일이 존재하지 않을 때 기본 dict를 반환한다"""
        missing = tmp_path / "config" / "teams.json"
        monkeypatch.setattr(_mod, "CONFIG_FILE", missing)

        config = _mod.load_config()
        assert config == {"version": "1.0", "teams": {}, "metadata": {}}

    def test_load_config_has_teams_key(self, setup_config):
        """로드된 config에 'teams' 키가 있다"""
        config = _mod.load_config()
        assert "teams" in config

    def test_load_config_returns_dict(self, setup_config):
        """load_config()는 dict를 반환한다"""
        config = _mod.load_config()
        assert isinstance(config, dict)

    def test_load_config_team_data_correct(self, setup_config):
        """dev1-team의 name이 '개발1팀'이다"""
        config = _mod.load_config()
        assert config["teams"]["dev1-team"]["name"] == "개발1팀"

    def test_load_config_default_has_empty_teams(self, tmp_path, monkeypatch):
        """파일 없을 때 반환되는 기본값의 teams는 빈 dict이다"""
        missing = tmp_path / "nonexistent" / "teams.json"
        monkeypatch.setattr(_mod, "CONFIG_FILE", missing)

        config = _mod.load_config()
        assert config["teams"] == {}


# ---------------------------------------------------------------------------
# TestSaveConfig
# ---------------------------------------------------------------------------


class TestSaveConfig:
    """save_config() 함수 테스트"""

    def test_save_config_creates_file(self, empty_config, tmp_path):
        """save_config() 호출 후 파일이 생성된다"""
        config = {"version": "1.0", "teams": {}, "metadata": {}}
        _mod.save_config(config)

        config_file = tmp_path / "config" / "teams.json"
        assert config_file.exists()

    def test_save_config_updates_metadata(self, empty_config, tmp_path):
        """metadata 필드(total_teams, active_teams, planned_teams, total_members)가 올바르게 계산된다"""
        config = {
            "version": "1.0",
            "teams": {
                "team-a": {"name": "팀A", "status": "active", "members": ["alice", "bob"]},
                "team-b": {"name": "팀B", "status": "planned", "members": []},
                "team-c": {"name": "팀C", "status": "active", "members": ["charlie"]},
            },
            "metadata": {},
        }
        _mod.save_config(config)

        saved = json.loads((tmp_path / "config" / "teams.json").read_text(encoding="utf-8"))
        assert saved["metadata"]["total_teams"] == 3
        assert saved["metadata"]["active_teams"] == 2
        assert saved["metadata"]["planned_teams"] == 1
        assert saved["metadata"]["total_members"] == 3

    def test_save_config_sets_updated_timestamp(self, empty_config, tmp_path):
        """'updated' 필드가 YYYY-MM-DD HH:MM:SS 형식으로 설정된다"""
        config = {"version": "1.0", "teams": {}, "metadata": {}}
        before = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        _mod.save_config(config)
        after = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        saved = json.loads((tmp_path / "config" / "teams.json").read_text(encoding="utf-8"))
        assert "updated" in saved
        # 저장된 타임스탬프가 호출 전후 사이에 있다
        assert before <= saved["updated"] <= after

    def test_save_config_persists_teams(self, empty_config, tmp_path):
        """teams 데이터가 파일에 올바르게 저장된다"""
        config = {
            "version": "1.0",
            "teams": {
                "new-team": {"name": "신규팀", "type": "수직조직", "status": "planned", "members": []}
            },
            "metadata": {},
        }
        _mod.save_config(config)

        saved = json.loads((tmp_path / "config" / "teams.json").read_text(encoding="utf-8"))
        assert "new-team" in saved["teams"]
        assert saved["teams"]["new-team"]["name"] == "신규팀"

    def test_save_config_creates_parent_dir(self, tmp_path, monkeypatch):
        """CONFIG_FILE의 부모 디렉터리가 없어도 자동 생성된다"""
        config_file = tmp_path / "nested" / "deep" / "teams.json"
        teams_dir = tmp_path / "teams"
        teams_dir.mkdir()
        monkeypatch.setattr(_mod, "CONFIG_FILE", config_file)
        monkeypatch.setattr(_mod, "TEAMS_DIR", teams_dir)

        config = {"version": "1.0", "teams": {}, "metadata": {}}
        _mod.save_config(config)

        assert config_file.exists()

    def test_save_config_empty_teams_metadata(self, empty_config, tmp_path):
        """teams가 빈 dict일 때 metadata 카운트가 모두 0이다"""
        config = {"version": "1.0", "teams": {}, "metadata": {}}
        _mod.save_config(config)

        saved = json.loads((tmp_path / "config" / "teams.json").read_text(encoding="utf-8"))
        assert saved["metadata"]["total_teams"] == 0
        assert saved["metadata"]["active_teams"] == 0
        assert saved["metadata"]["planned_teams"] == 0
        assert saved["metadata"]["total_members"] == 0

    def test_save_config_valid_json(self, empty_config, tmp_path):
        """저장된 파일이 유효한 JSON이다"""
        config = {"version": "1.0", "teams": {"t": {"name": "팀", "status": "active", "members": []}}, "metadata": {}}
        _mod.save_config(config)

        content = (tmp_path / "config" / "teams.json").read_text(encoding="utf-8")
        parsed = json.loads(content)
        assert isinstance(parsed, dict)


# ---------------------------------------------------------------------------
# TestGenerateTeamId
# ---------------------------------------------------------------------------


class TestGenerateTeamId:
    """generate_team_id() 함수 테스트"""

    def test_korean_to_english_conversion(self):
        """'개발팀' → 'devteam' 로 변환된다"""
        result = _mod.generate_team_id("개발팀")
        assert result == "devteam"

    def test_spaces_to_hyphens(self):
        """공백은 하이픈으로 변환된다: 'AI 팀' → 'ai-team'"""
        result = _mod.generate_team_id("AI 팀")
        assert result == "ai-team"

    def test_lowercase(self):
        """결과는 소문자로 반환된다"""
        result = _mod.generate_team_id("DEV팀")
        # 'DEV' → 'dev', '팀' → 'team'
        assert result == result.lower()

    def test_special_chars_removed(self):
        """알파벳, 숫자, 하이픈 외의 특수문자는 제거된다"""
        result = _mod.generate_team_id("개발@#$팀!")
        # @#$! 제거, 한글 변환 후 영문+하이픈만 남아야 함
        for ch in result:
            assert ch.isalnum() or ch == "-"

    def test_dev_mapping(self):
        """'개발' → 'dev' 로 매핑된다"""
        result = _mod.generate_team_id("개발")
        assert "dev" in result

    def test_team_mapping(self):
        """'팀' → 'team' 으로 매핑된다"""
        result = _mod.generate_team_id("팀")
        assert "team" in result

    def test_center_mapping(self):
        """'센터' → 'center' 로 매핑된다"""
        result = _mod.generate_team_id("디자인 센터")
        assert "center" in result

    def test_marketing_mapping(self):
        """'마케팅' → 'marketing' 으로 매핑된다"""
        result = _mod.generate_team_id("마케팅팀")
        assert "marketing" in result

    def test_insurance_mapping(self):
        """'보험' → 'insurance' 로 매핑된다"""
        result = _mod.generate_team_id("보험팀")
        assert "insurance" in result

    def test_design_mapping(self):
        """'디자인' → 'design' 으로 매핑된다"""
        result = _mod.generate_team_id("디자인팀")
        assert "design" in result

    def test_red_mapping(self):
        """'레드' → 'red' 로 매핑된다"""
        result = _mod.generate_team_id("레드팀")
        assert "red" in result

    def test_strategy_mapping(self):
        """'전략' → 'strategy' 로 매핑된다"""
        result = _mod.generate_team_id("전략팀")
        assert "strategy" in result

    def test_hyphen_preserved(self):
        """기존 하이픈은 유지된다"""
        result = _mod.generate_team_id("dev1-team")
        assert "-" in result

    def test_returns_string(self):
        """반환값은 str 타입이다"""
        result = _mod.generate_team_id("개발팀")
        assert isinstance(result, str)

    def test_numeric_suffix_preserved(self):
        """숫자는 유지된다: 'dev1' → 'dev1'"""
        result = _mod.generate_team_id("개발1팀")
        assert "1" in result


# ---------------------------------------------------------------------------
# TestCreateTeamDirectory
# ---------------------------------------------------------------------------


class TestCreateTeamDirectory:
    """create_team_directory() 함수 테스트"""

    def test_creates_directory(self, empty_config, tmp_path):
        """팀 디렉터리가 생성된다"""
        _mod.create_team_directory("test-team", "테스트팀")
        assert (tmp_path / "teams" / "test-team").is_dir()

    def test_creates_readme(self, empty_config, tmp_path):
        """README.md가 생성된다"""
        _mod.create_team_directory("test-team", "테스트팀")
        readme = tmp_path / "teams" / "test-team" / "README.md"
        assert readme.exists()

    def test_readme_contains_team_name(self, empty_config, tmp_path):
        """README.md에 팀 이름이 포함된다"""
        _mod.create_team_directory("test-team", "테스트팀")
        readme = tmp_path / "teams" / "test-team" / "README.md"
        content = readme.read_text(encoding="utf-8")
        assert "테스트팀" in content

    def test_creates_subdirs(self, empty_config, tmp_path):
        """src/, tests/, docs/ 하위 디렉터리가 생성된다"""
        _mod.create_team_directory("test-team", "테스트팀")
        team_dir = tmp_path / "teams" / "test-team"
        assert (team_dir / "src").is_dir()
        assert (team_dir / "tests").is_dir()
        assert (team_dir / "docs").is_dir()

    def test_creates_gitkeep_in_src(self, empty_config, tmp_path):
        """src/.gitkeep이 생성된다"""
        _mod.create_team_directory("test-team", "테스트팀")
        assert (tmp_path / "teams" / "test-team" / "src" / ".gitkeep").exists()

    def test_creates_gitkeep_in_tests(self, empty_config, tmp_path):
        """tests/.gitkeep이 생성된다"""
        _mod.create_team_directory("test-team", "테스트팀")
        assert (tmp_path / "teams" / "test-team" / "tests" / ".gitkeep").exists()

    def test_readme_not_overwritten(self, empty_config, tmp_path):
        """README.md가 이미 존재하면 덮어쓰지 않는다"""
        team_dir = tmp_path / "teams" / "test-team"
        team_dir.mkdir(parents=True)
        readme = team_dir / "README.md"
        original_content = "# 기존 README 내용"
        readme.write_text(original_content, encoding="utf-8")

        _mod.create_team_directory("test-team", "테스트팀")

        assert readme.read_text(encoding="utf-8") == original_content

    def test_returns_path(self, empty_config, tmp_path):
        """반환값이 Path 객체이다"""
        result = _mod.create_team_directory("test-team", "테스트팀")
        assert isinstance(result, Path)

    def test_returns_correct_path(self, empty_config, tmp_path):
        """반환된 Path가 실제 팀 디렉터리를 가리킨다"""
        result = _mod.create_team_directory("test-team", "테스트팀")
        assert result == tmp_path / "teams" / "test-team"

    def test_idempotent_call(self, empty_config, tmp_path):
        """두 번 호출해도 오류 없이 동작한다 (exist_ok=True)"""
        _mod.create_team_directory("test-team", "테스트팀")
        # 두 번째 호출 — 예외 없이 통과해야 함
        _mod.create_team_directory("test-team", "테스트팀")
        assert (tmp_path / "teams" / "test-team").is_dir()


# ---------------------------------------------------------------------------
# TestAddTeam
# ---------------------------------------------------------------------------


class TestAddTeam:
    """add_team() 함수 테스트"""

    def test_add_new_team(self, empty_config, tmp_path):
        """새 팀을 추가하면 config에 저장되고 디렉터리가 생성된다"""
        result = _mod.add_team(name="신규팀", team_type="수직조직", lead="zeus", status="planned")

        # config 파일에 저장되었는지 확인
        saved = json.loads((tmp_path / "config" / "teams.json").read_text(encoding="utf-8"))
        team_id = result["team_id"]
        assert team_id in saved["teams"]

        # 디렉터리가 생성되었는지 확인
        assert (tmp_path / "teams" / team_id).is_dir()

    def test_duplicate_team_exits(self, setup_config):
        """이미 존재하는 team_id로 추가 시 sys.exit(1)이 호출된다"""
        # setup_config에는 'dev1-team'이 존재 (generate_team_id("개발1팀") == "dev1team" 이지만
        # 직접 동일 ID가 나오는 이름을 사용)
        # 먼저 'dev1-team'과 동일한 ID가 나오는 이름으로 테스트:
        # load_config()로 현재 팀 ID 확인
        config = _mod.load_config()
        existing_id = list(config["teams"].keys())[0]  # "dev1-team"

        # generate_team_id가 existing_id를 반환하도록 하는 이름 직접 사용
        # 방법: config에 직접 패치된 팀 ID와 동일하게 들어갈 이름을 찾는 대신
        # 직접 config에 새 팀을 추가하고 같은 이름으로 두 번 호출
        with pytest.raises(SystemExit) as exc_info:
            _mod.add_team(name="개발1팀", team_type="수직조직")
            _mod.add_team(name="개발1팀", team_type="수직조직")
        assert exc_info.value.code == 1

    def test_duplicate_team_id_detected(self, empty_config):
        """첫 번째 add 이후 동일 이름으로 다시 추가하면 sys.exit(1)"""
        _mod.add_team(name="AI팀", team_type="수직조직", status="planned")

        with pytest.raises(SystemExit) as exc_info:
            _mod.add_team(name="AI팀", team_type="수직조직", status="planned")
        assert exc_info.value.code == 1

    def test_team_info_structure(self, empty_config):
        """반환된 dict에 team_id, team_info, directory 키가 있다"""
        result = _mod.add_team(name="테스트팀", team_type="수직조직")
        assert "team_id" in result
        assert "team_info" in result
        assert "directory" in result

    def test_team_info_contains_required_fields(self, empty_config):
        """team_info에 name, type, status, lead, members, created_at이 있다"""
        result = _mod.add_team(name="테스트팀", team_type="수직조직", lead="zeus")
        info = result["team_info"]
        assert info["name"] == "테스트팀"
        assert info["type"] == "수직조직"
        assert "status" in info
        assert "lead" in info
        assert "members" in info
        assert "created_at" in info

    def test_default_status_planned(self, empty_config):
        """status 미지정 시 기본값은 'planned'이다"""
        result = _mod.add_team(name="기본상태팀", team_type="수직조직")
        assert result["team_info"]["status"] == "planned"

    def test_members_default_empty(self, empty_config):
        """members 미지정 시 기본값은 빈 리스트이다"""
        result = _mod.add_team(name="빈멤버팀", team_type="수직조직")
        assert result["team_info"]["members"] == []

    def test_lead_stored_correctly(self, empty_config):
        """lead가 team_info에 올바르게 저장된다"""
        result = _mod.add_team(name="리더팀", team_type="수직조직", lead="poseidon")
        assert result["team_info"]["lead"] == "poseidon"

    def test_members_stored_correctly(self, empty_config):
        """전달된 members가 team_info에 저장된다"""
        result = _mod.add_team(name="멤버팀", team_type="수직조직", members=["alice", "bob"])
        assert result["team_info"]["members"] == ["alice", "bob"]

    def test_active_status_stored(self, empty_config):
        """status='active'가 올바르게 저장된다"""
        result = _mod.add_team(name="활성팀", team_type="수직조직", status="active")
        assert result["team_info"]["status"] == "active"

    def test_team_type_stored(self, empty_config):
        """team_type이 team_info에 올바르게 저장된다"""
        result = _mod.add_team(name="횡단조직팀", team_type="횡단조직")
        assert result["team_info"]["type"] == "횡단조직"

    def test_created_at_format(self, empty_config):
        """created_at이 YYYY-MM-DD HH:MM:SS 형식이다"""
        result = _mod.add_team(name="타임스탬프팀", team_type="수직조직")
        created_at = result["team_info"]["created_at"]
        # strptime으로 파싱 가능해야 함
        datetime.strptime(created_at, "%Y-%m-%d %H:%M:%S")

    def test_directory_created(self, empty_config, tmp_path):
        """add_team() 후 팀 디렉터리가 실제로 생성된다"""
        result = _mod.add_team(name="디렉팀", team_type="수직조직")
        team_dir = Path(result["directory"])
        assert team_dir.is_dir()

    def test_config_saved_to_file(self, empty_config, tmp_path):
        """add_team() 후 config 파일에 팀 정보가 저장된다"""
        result = _mod.add_team(name="저장팀", team_type="수직조직")
        saved = json.loads((tmp_path / "config" / "teams.json").read_text(encoding="utf-8"))
        assert result["team_id"] in saved["teams"]


# ---------------------------------------------------------------------------
# TestListTeams
# ---------------------------------------------------------------------------


class TestListTeams:
    """list_teams() 함수 테스트"""

    def test_list_teams_with_data(self, setup_config, capsys):
        """팀이 있을 때 팀 정보를 출력한다"""
        _mod.list_teams()
        captured = capsys.readouterr()
        assert "dev1-team" in captured.out

    def test_list_teams_empty(self, empty_config, capsys):
        """팀이 없을 때 '등록된 팀이 없습니다.'를 출력한다"""
        _mod.list_teams()
        captured = capsys.readouterr()
        assert "등록된 팀이 없습니다." in captured.out

    def test_list_teams_shows_team_name(self, setup_config, capsys):
        """팀 이름('개발1팀')이 출력에 포함된다"""
        _mod.list_teams()
        captured = capsys.readouterr()
        assert "개발1팀" in captured.out

    def test_list_teams_shows_lead(self, setup_config, capsys):
        """팀 리더('hermes')가 출력에 포함된다"""
        _mod.list_teams()
        captured = capsys.readouterr()
        assert "hermes" in captured.out

    def test_list_teams_shows_member_count(self, setup_config, capsys):
        """팀원 수(4명)가 출력에 포함된다"""
        _mod.list_teams()
        captured = capsys.readouterr()
        assert "4" in captured.out

    def test_list_teams_shows_total(self, setup_config, capsys):
        """총 팀 수가 출력에 포함된다"""
        _mod.list_teams()
        captured = capsys.readouterr()
        assert "총" in captured.out

    def test_list_teams_shows_type(self, setup_config, capsys):
        """팀 유형('수직조직')이 출력에 포함된다"""
        _mod.list_teams()
        captured = capsys.readouterr()
        assert "수직조직" in captured.out

    def test_list_teams_shows_separator(self, setup_config, capsys):
        """구분선('=')이 출력에 포함된다"""
        _mod.list_teams()
        captured = capsys.readouterr()
        assert "=" * 10 in captured.out

    def test_list_teams_multiple_teams(self, empty_config, tmp_path, capsys):
        """여러 팀이 있을 때 모두 출력된다"""
        _mod.add_team(name="팀알파", team_type="수직조직")
        _mod.add_team(name="팀베타", team_type="횡단조직")

        _mod.list_teams()
        captured = capsys.readouterr()
        assert "팀알파" in captured.out
        assert "팀베타" in captured.out

    def test_list_teams_returns_none(self, setup_config):
        """list_teams()는 None을 반환한다"""
        result = _mod.list_teams()
        assert result is None


# ---------------------------------------------------------------------------
# TestCLIMain
# ---------------------------------------------------------------------------


class TestCLIMain:
    """main() CLI 함수 테스트"""

    def test_list_flag(self, setup_config, monkeypatch, capsys):
        """--list 플래그로 팀 목록이 출력된다"""
        monkeypatch.setattr(sys, "argv", ["add-team.py", "--list"])
        _mod.main()
        captured = capsys.readouterr()
        assert "dev1-team" in captured.out

    def test_list_flag_short(self, setup_config, monkeypatch, capsys):
        """--list 플래그 실행 후 반환 (add_team이 호출되지 않음)"""
        monkeypatch.setattr(sys, "argv", ["add-team.py", "--list"])
        # main()이 sys.exit 없이 정상 종료
        _mod.main()

    def test_add_team_via_cli(self, empty_config, tmp_path, monkeypatch, capsys):
        """--name과 --type이 제공되면 팀이 추가된다"""
        monkeypatch.setattr(
            sys, "argv",
            ["add-team.py", "--name", "CLI테스트팀", "--type", "수직조직"]
        )
        _mod.main()

        saved = json.loads((tmp_path / "config" / "teams.json").read_text(encoding="utf-8"))
        assert len(saved["teams"]) == 1

    def test_add_team_cli_output(self, empty_config, monkeypatch, capsys):
        """팀 추가 성공 시 성공 메시지가 출력된다"""
        monkeypatch.setattr(
            sys, "argv",
            ["add-team.py", "--name", "출력테스트팀", "--type", "수직조직", "--lead", "zeus"]
        )
        _mod.main()
        captured = capsys.readouterr()
        assert "완료" in captured.out or "✅" in captured.out

    def test_missing_required_name_exits(self, empty_config, monkeypatch):
        """--name이 없으면 sys.exit(1)이 호출된다"""
        monkeypatch.setattr(sys, "argv", ["add-team.py", "--type", "수직조직"])
        with pytest.raises(SystemExit) as exc_info:
            _mod.main()
        assert exc_info.value.code == 1

    def test_missing_required_type_exits(self, empty_config, monkeypatch):
        """--type이 없으면 sys.exit(1)이 호출된다"""
        monkeypatch.setattr(sys, "argv", ["add-team.py", "--name", "타입없는팀"])
        with pytest.raises(SystemExit) as exc_info:
            _mod.main()
        assert exc_info.value.code == 1

    def test_no_args_exits(self, empty_config, monkeypatch):
        """인수 없이 실행하면 sys.exit(1)이 호출된다"""
        monkeypatch.setattr(sys, "argv", ["add-team.py"])
        with pytest.raises(SystemExit) as exc_info:
            _mod.main()
        assert exc_info.value.code == 1

    def test_cli_with_lead_and_status(self, empty_config, tmp_path, monkeypatch):
        """--lead, --status 인수가 팀 정보에 반영된다"""
        monkeypatch.setattr(
            sys, "argv",
            [
                "add-team.py",
                "--name", "리더상태팀",
                "--type", "수직조직",
                "--lead", "apollo",
                "--status", "active",
            ]
        )
        _mod.main()

        saved = json.loads((tmp_path / "config" / "teams.json").read_text(encoding="utf-8"))
        team = list(saved["teams"].values())[0]
        assert team["lead"] == "apollo"
        assert team["status"] == "active"

    def test_cli_with_members(self, empty_config, tmp_path, monkeypatch):
        """--members 인수가 팀 멤버에 반영된다"""
        monkeypatch.setattr(
            sys, "argv",
            [
                "add-team.py",
                "--name", "멤버팀",
                "--type", "수직조직",
                "--members", "alice", "bob",
            ]
        )
        _mod.main()

        saved = json.loads((tmp_path / "config" / "teams.json").read_text(encoding="utf-8"))
        team = list(saved["teams"].values())[0]
        assert "alice" in team["members"]
        assert "bob" in team["members"]

    def test_cli_invalid_type_exits(self, empty_config, monkeypatch):
        """--type에 유효하지 않은 값을 전달하면 sys.exit이 호출된다 (argparse choices 검증)"""
        monkeypatch.setattr(
            sys, "argv",
            ["add-team.py", "--name", "잘못된유형팀", "--type", "잘못된유형"]
        )
        with pytest.raises(SystemExit):
            _mod.main()

    def test_cli_invalid_status_exits(self, empty_config, monkeypatch):
        """--status에 유효하지 않은 값을 전달하면 sys.exit이 호출된다 (argparse choices 검증)"""
        monkeypatch.setattr(
            sys, "argv",
            ["add-team.py", "--name", "잘못된상태팀", "--type", "수직조직", "--status", "invalid"]
        )
        with pytest.raises(SystemExit):
            _mod.main()

    def test_cli_list_empty_config(self, empty_config, monkeypatch, capsys):
        """팀이 없을 때 --list는 '등록된 팀이 없습니다.'를 출력한다"""
        monkeypatch.setattr(sys, "argv", ["add-team.py", "--list"])
        _mod.main()
        captured = capsys.readouterr()
        assert "등록된 팀이 없습니다." in captured.out
